none
Prevent changes to the CS file(s) generated by Entity Framework RRS feed

  • Question

  • I want to make changes to the cs files generated by Entity Framework.

    But I want to keep those  code changes even when updating from the database

    i.e. if I add INotifyPropertyChanged and events to all the generated properties I don't want to lose those changes.

    How do I accomplish this?


    jawsurgeon

    Wednesday, March 16, 2016 3:19 PM

Answers

  • Andy:

    Thanks for that.

    I guess that works for even multiple row edits..the save button will save all the changes to every row that has been changed....correct?

    Thank makes much more sense.

    ...too bad all this stuff isn't laid out logically in all the references that I have sitting on my desk!

    ..Adam


    jawsurgeon

    The dbcontext has a change tracking mechanism. When you call SaveChanges it knows that an entity has been edited. When an entity instance is added to one of the collections associated with a dbcontext then it knows that's ready to be inserted.

    It'll apply the appropriate sql for each changed entity it has tracked.

    You're usually best forcing them to work with one at a time though.

    Otherwise, you get problems with stuff like validation failures. Which record needs fixing?

    Anyhow, couple of pieces of code from:

    https://gallery.technet.microsoft.com/WPF-Entity-Framework-MVVM-78cdc204

    Changetracker knows if there are any changes:

            protected override void CommitUpdates()
            {
                if (EditVM == null || EditVM.TheEntity == null)
                {
                    if (db.ChangeTracker.HasChanges())
                    {
                        UpdateDB();
                    }
                    return;
                }
                if (EditVM.TheEntity.IsValid())
                {
                    if (EditVM.IsNew)
                    {
                        EditVM.IsNew = false;
                        Customers.Add(EditVM);
                        db.Customers.Add(EditVM.TheEntity);
                        UpdateDB();
                    }
                    else if (db.ChangeTracker.HasChanges())
                    {
                        UpdateDB();
                    }
                    else
                    {
                        ShowUserMessage("No changes to save");
                    }
                }
                else
                {
                    ShowUserMessage("There are problems with the data entered");
                }
            }

    Deletion

            protected override void DeleteCurrent()
            {
                int NumOrders = NumberOfOrders();
                if (NumOrders > 0)
                {
                    ShowUserMessage( string.Format("Cannot delete - there are {0} Orders for this Customer", NumOrders));
                }
                else
                {
                    db.Customers.Remove(SelectedCustomer.TheEntity);
                    Customers.Remove(SelectedCustomer);
                    RaisePropertyChanged("Customers");
                    CommitUpdates();
                    selectedEntity = null;
                }
            }


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    Tuesday, March 29, 2016 9:43 AM

All replies

  • Hi jawsurgeon,

    Like your tltle mentioned, your case more related to Entity Framework, I will help move your case to EF forum for better support.

    Best regards,

    Kristin


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Thursday, March 17, 2016 2:10 AM
  • Hi Jawsurgeon,

    >>But I want to keep those code changes even when updating from the database

    Per your description, you want to keep your code changes when updating the model from the database. I would suggest that you create a new partial class which has the same name with your model class. then you make any changes on this partial class, you also could inherit interface named INotifyPropertyChanged.

    For more information about partial class, please refer to the following link.

    https://msdn.microsoft.com/en-us/library/wa80x488.aspx

    Best regards,

    Cole Wu

    Thursday, March 17, 2016 8:12 AM
    Moderator

  •  If I want to implement getter and setter code on a property that property can't exist in both files?

    so that is a  problem.

    for instance if 

    PtFName {get;set:} is automatically generated every time I update the db model

    However,

    I want to keep the Property Changed code associated with that property and a seperate partial class file.

    That means I will have to delete those properties within the code-generated partial class every time I regenerate the model.

    right?


    jawsurgeon


    • Edited by Jawsurgeon Thursday, March 17, 2016 12:51 PM
    Thursday, March 17, 2016 12:46 PM
  • That means I will have to delete those properties within the code-generated partial class every time I regenerate the model.

    right?

    It means that you are headed for trouble.  That's what that means. You should leave auto generated code alone.

    Thursday, March 17, 2016 11:16 PM
  • I think this thread should probably have been left or moved in the wpf forum.

    JawSurgeon does wpf development and the real answer to this question is connected to MVVM.

    .

    I use partial classes with entity framework to add buddy classes for validation via metadata and the base class for validation.

    When I need inotifypropertychanged I wrap the entity framework property with a viewmodel property.

    To give you a flavour, let's imagine I have an entity for Order. This is a ridiculously simplified sort of an entity and it has Quantity and Price ( per unit ). The total for an order is Qty * Price which is calculated. ( As I said this is grossly simplified ).

    I want to show a recalculated total when either quantity of price changed.

    So I have a viewmodel OrderVM which wraps Order:

        public class OrderVM : ViewModelBase
        {
            private Order theOrder;
    
            public Order TheOrder
            {
                get { return theOrder; }
                set { theOrder = value; RaisePropertyChanged(); }
            }
            public double Qty
            {
                get
                {
                    return TheOrder.Qty;
                }
                set
                {
                    TheOrder.Qty = value;
                    RaisePropertyChanged();
                    Calculate();
                }
            }
            public decimal Price
            {
                get
                {
                    return TheOrder.Price;
                }
                set
                {
                    TheOrder.Price = value;
                    RaisePropertyChanged();
                    Calculate();
                }
            }
            private void Calculate()
            {
                TheOrder.Total = (decimal) (TheOrder.Qty * (double)TheOrder.Price);
                RaisePropertyChanged("TheOrder.Total");
            }

    That way  inotifypropertychanged works fine and I haven't polluted my model.

    .

    Some people prefer to change the T4 remplate so it generates RaisePropertyChanged on every property. This is a bad idea IMO.

    .

    Often, you don't need any of that though. Mostly users are editing or reading. They don't really edit and expect to see stuff change as they do so.

    When they commit a change, they might expect to see a whole record's worth of data change but otherwise not so much. You can often rely on an observablecollection and collectionchanged to handle that. If you set an item of an observablecollection to itself it raises collectionchanged.

    For example in this:

    https://gallery.technet.microsoft.com/WPF-Entity-Framework-MVVM-78cdc204

    The user edits in a control which overlays a datagrid (  validation in a datagrid is impractical ).

    Once completed you hit the save button and you can see your changes appear in the matching row in the datagrid. This is because I use that technique:

                if (!EditVM.IsNew)
                {
                    EditVM.TheEntity.ClearErrors();
                    await db.Entry(EditVM.TheEntity).ReloadAsync();
                    // Force the datagrid to realise the record has changed
                    EditVM.TheEntity = EditVM.TheEntity;
                    RaisePropertyChanged("EditVM");
                }


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    • Proposed as answer by Feifeifei2016 Tuesday, March 29, 2016 2:11 AM
    Friday, March 25, 2016 8:01 PM
  • Andy:

    Thanks for that.

    I guess that works for even multiple row edits..the save button will save all the changes to every row that has been changed....correct?

    Thank makes much more sense.

    ...too bad all this stuff isn't laid out logically in all the references that I have sitting on my desk!

    ..Adam


    jawsurgeon

    Saturday, March 26, 2016 11:57 AM
  • Hi,

    the simple method is backup your code before you update model from database.

    Tuesday, March 29, 2016 2:31 AM
  • Andy:

    Thanks for that.

    I guess that works for even multiple row edits..the save button will save all the changes to every row that has been changed....correct?

    Thank makes much more sense.

    ...too bad all this stuff isn't laid out logically in all the references that I have sitting on my desk!

    ..Adam


    jawsurgeon

    The dbcontext has a change tracking mechanism. When you call SaveChanges it knows that an entity has been edited. When an entity instance is added to one of the collections associated with a dbcontext then it knows that's ready to be inserted.

    It'll apply the appropriate sql for each changed entity it has tracked.

    You're usually best forcing them to work with one at a time though.

    Otherwise, you get problems with stuff like validation failures. Which record needs fixing?

    Anyhow, couple of pieces of code from:

    https://gallery.technet.microsoft.com/WPF-Entity-Framework-MVVM-78cdc204

    Changetracker knows if there are any changes:

            protected override void CommitUpdates()
            {
                if (EditVM == null || EditVM.TheEntity == null)
                {
                    if (db.ChangeTracker.HasChanges())
                    {
                        UpdateDB();
                    }
                    return;
                }
                if (EditVM.TheEntity.IsValid())
                {
                    if (EditVM.IsNew)
                    {
                        EditVM.IsNew = false;
                        Customers.Add(EditVM);
                        db.Customers.Add(EditVM.TheEntity);
                        UpdateDB();
                    }
                    else if (db.ChangeTracker.HasChanges())
                    {
                        UpdateDB();
                    }
                    else
                    {
                        ShowUserMessage("No changes to save");
                    }
                }
                else
                {
                    ShowUserMessage("There are problems with the data entered");
                }
            }

    Deletion

            protected override void DeleteCurrent()
            {
                int NumOrders = NumberOfOrders();
                if (NumOrders > 0)
                {
                    ShowUserMessage( string.Format("Cannot delete - there are {0} Orders for this Customer", NumOrders));
                }
                else
                {
                    db.Customers.Remove(SelectedCustomer.TheEntity);
                    Customers.Remove(SelectedCustomer);
                    RaisePropertyChanged("Customers");
                    CommitUpdates();
                    selectedEntity = null;
                }
            }


    Hope that helps.

    Technet articles: WPF: Layout Lab; All my Technet Articles

    Tuesday, March 29, 2016 9:43 AM