Is it possible perform actions in POCO before insert/update?

夙愿已清 提交于 2020-01-03 00:24:12

问题


Let's assume this Entity Framework sample:

public class User
{ 
    public int UserID { get; set; } 
    public string Name { get; set; }      
} 

public class MyDbContext : DbContext 
{ 
    public DbSet<User> Users { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
        using (var db = new MyDbContext ()) 
        {     
            var user = new User { Name = "Foo"}; 
            db.Users.Add(user); 
            db.SaveChanges();      

            Console.WriteLine("Press any key to exit..."); 
            Console.ReadKey(); 
        } 
    } 
}

I want add to User class events, like "BeforeInsert" or "BeforeUpdate", and when the code...

db.Users.Add(user); 

... is executed anywhere in the application, the "BeforeInsert" method will be raised. Is it possible?


回答1:


@JC's answer is correct. I will just show code, in which you can do what you want. First of all, override SaveChanges method in your context, and call this overriden SaveChanges method: context.SaveChanges(true) instead of conntext.SaveChanges()

public class MyDbContext : DbContext 
{ 
    public DbSet<User> Users { get; set; } 

    public int SaveChanges(bool performCustomOperations)
    {
        if(performCustomOperations)
        {
            CustomContextManager contextManager = new CustomContextManager(this);
            //Perform operations you want before saving data
            contextManager.PerformBeforeUpdate();

            //To do: Add your own PerformBeforeInsert method to CustomContextManager class
        }

        //Save changes to underlying database
        this.SaveChanges();
    }
} 

Your CustomContextManager class should look like this. Performing your before update operations in PerformBeforeUpdate method. You can add your own PerformBeforeInsert and/or PerformBeforeDelete methods.

public class CustomContextManager
{
    private MyDbContext context;

    public CustomContextManager(MyDbContext contextParam)
    {
        if (contextParam == null)
            throw new ArgumentNUllException(nameof(contextParam));

        this.context = contextParam;
    }

    public void PerformBeforeUpdate
    {
        //Get object context to be able to perform operations
        System.Data.Objects.ObjectContext myObjectContext =
            ((IObjectContextAdapter)context).ObjectContext;

        IEnumerable<ObjectStateEntry> updatedRecords =
            taxesObjectContext.ObjectStateManager.GetObjectStateEntries(
            System.Data.EntityState.Modified);

        if (updatedRecords != null
            && updatedRecords.Count() > 0)
        {
            foreach (ObjectStateEntry stateEntry in updatedRecords)
            {
                if (stateEntry != null
                    && stateEntry.Entity != null)
                {
                    //Do what operations you want instead of below linnes
                    User modifiedUser = stateEntry.Entity as User;
                    if(modifiedUser != null)
                        modifiedUser.Name = "Altered before update";
                }
            }
        }
    }
}



回答2:


You want to do that in an override of the SaveChanges() method of your DbContext. Scan through the ChangeTracker.Entries collection for any entries of your type. Then for each of those, do your BeforeInsert or BeforeUpdate operations based on whether entry.State is EntityState.Added or EntityState.Modified.



来源:https://stackoverflow.com/questions/28576033/is-it-possible-perform-actions-in-poco-before-insert-update

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!