是否可以在 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" 方法。可能吗?
您想在覆盖 DbContext
的 SaveChanges()
方法时执行此操作。浏览 ChangeTracker.Entries
集合以查找您的类型的任何条目。然后对于其中的每一个,根据 entry.State
是 EntityState.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";
}
}
}
}
}
让我们假设这个 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" 方法。可能吗?
您想在覆盖 DbContext
的 SaveChanges()
方法时执行此操作。浏览 ChangeTracker.Entries
集合以查找您的类型的任何条目。然后对于其中的每一个,根据 entry.State
是 EntityState.Added
还是 EntityState.Modified
.
@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";
}
}
}
}
}