是否可以在插入/更新之前在POCO中执行操作?

时间:2015-02-18 04:31:46

标签: c# entity-framework ef-code-first

让我们假设这个实体框架示例:

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(); 
        } 
    } 
}

我想添加用户类事件,例如&#34; BeforeInsert&#34;或&#34; BeforeUpdate&#34;,以及代码......

db.Users.Add(user); 

...在应用程序的任何地方执行,&#34; BeforeInsert&#34;方法将被提出。可能吗?

2 个答案:

答案 0 :(得分:2)

您希望覆盖SaveChanges()的{​​{1}}方法。浏览DbContext集合,查看您所输入的任何条目。然后针对其中的每一个,根据ChangeTracker.Entriesentry.State还是EntityState.Added来执行BeforeInsert或BeforeUpdate操作。

答案 1 :(得分:2)

@ JC的回答是正确的。我将只显示代码,您可以在其中执行您想要的操作。首先,在您的上下文中覆盖SaveChanges方法,并调用此覆盖SaveChanges方法: context.SaveChanges(true)而不是 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();
    }
} 

您的CustomContextManager类应如下所示。在 PerformBeforeUpdate 方法中执行更新前操作。您可以添加自己的 PerformBeforeInsert和/或PerformBeforeDelete 方法。

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";
                }
            }
        }
    }
}