是否可以在 insert/update 之前在 POCO 中执行操作?

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

让我们假设这个 Entity Framework 样本:

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

我想添加到 User class 事件,例如 "BeforeInsert" 或 "BeforeUpdate",当代码...

db.Users.Add(user); 

... 在应用程序的任何位置执行,都会引发 "BeforeInsert" 方法。可能吗?

您想在覆盖 DbContextSaveChanges() 方法时执行此操作。浏览 ChangeTracker.Entries 集合以查找您的类型的任何条目。然后对于其中的每一个,根据 entry.StateEntityState.Added 还是 EntityState.Modified.

执行 BeforeInsert 或 BeforeUpdate 操作

@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 class 应该如下所示。在 PerformBeforeUpdate 方法中执行更新前的操作。您可以添加自己的 PerformBeforeInsert and/or 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";
                }
            }
        }
    }
}