问题
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