我希望为实体框架存储的类之一自动创建和修改列。
我找到了这个巧妙的解决方案,它让我成功了一半。
https://stackoverflow.com/a/53669556/392485(我不确定政策是否应该在此处包含一些答案以供清楚起见,因为它不在外部站点上)
但是,在我的数据结构中,我有与子级相关的实体,如果修改了这些实体,我想更新父级的修改日期,下面是我的数据结构的简化版本。
public class Recipe : IAuditableModel
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime Created { get; set; } = DateTime.Now;
public DateTime? Modified { get; set; }
public ObservableCollection<Step> Steps { get; set; } = new ObservableCollection<Step>();
}
public class Step
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
使用上述解决方案,如果步骤数或每个步骤中的信息发生更改,Modified将永远不会更新。
Step 实体仅在通过 Recipe 实体访问时才会被修改。
我可以看到如何进一步修改 SaveChanges 覆盖来处理这种特殊情况,我希望有一个在 Linked IAuditableModel 上扩展的更清晰的解决方案,如果修改了任何对象导航属性,它也会更新修改。
我确实看到了 DbEntityEntry.Collection(string) 方法,但看不到如何找到集合的名称来提供此函数。
另外,我想知道我是否应该尝试通过放弃将步骤作为自己的实体来回避这个问题,并将它们直接序列化到食谱实体中。这样做意味着如果我将来对 Step 类进行更改,我会失去一些简洁的迁移功能。
这是一个简单的代码,您可以使用它:
public class YourDbContext : DbContext
{
public DbSet<Recipe> Recipes { get; set; }
public DbSet<Step> Steps { get; set; }
public override int SaveChanges()
{
var modifiedEntities = ChangeTracker.Entries()
.Where(e => e.State == EntityState.Modified &&
e.Entity is Step);
foreach (var entry in modifiedEntities)
{
var recipeId = entry.Property("RecipeId").CurrentValue;
var recipe = Recipes.Find(recipeId);
if (recipe != null)
{
recipe.Modified = DateTime.Now;
}
}
return base.SaveChanges();
}
}