[英]How to have a property in a parent entity whose value belongs to a child entity two levels down with EF6 and Code-First
I need to mantain udpated a property in a parent entity that belongs to a child entity two levels down. 我需要维护父级实体中的属性,该父级实体向下两级属于子实体。 I am using EF6 with Code First and DataAnnotations in a Asp.Net/MVC application.
我在Asp.Net/MVC应用程序中使用带有代码优先和DataAnnotations的EF6。
Having these entitites: 具有这些实体:
public class Parent
{
[Key]
public int IdParent {get; set;}
// ...other properties
//The value of this property belongs to the Child table, two levels down.
public int Status { get; set; }
public Intermediate Intermediate { get; set; }
}
public class Intermediate
{
[Key, ForeignKey("Parent")]
public int IdIntermediate { get; set;}
// ... other properties
public Parent Parent { get; set; }
public Child Child { get; set; }
}
public class Child
{
[Key, ForeignKey("Intermediate")]
public int IdChild { get; set; }
//...other properties
public int Status { get; set; } // This is the property I need to keep updated in Parent Class
public Intermediate Intermediate { get; set; }
}
The property Status in Parent gives to the user a quick view of the result of the process executed on Child which has detailed information about the execution. 父级中的状态状态为用户提供了在子级上执行的处理结果的快速视图,其中包含有关执行的详细信息。
I am evaluating these solution, I would appreciate your recommendations about which of them is more appropiate or another better solution. 我正在评估这些解决方案,对于您提出的建议中哪个更合适或更好,我将不胜感激。
Option 1: Create a trigger in database to keep updated the field in Parent table. 选项1:在数据库中创建一个触发器,以保持更新父表中的字段。 This option will produce a cleaner code in my entities but requires to create an isolated migration for the trigger because it has to be a SQL command, and it is hard to maintain.
此选项将在我的实体中产生更清晰的代码,但需要为触发器创建隔离的迁移,因为它必须是SQL命令,并且难以维护。
public partial class AddUpdateTriggerOnChildMigration : DbMigration { public override void Up() { Sql("CREATE OR REPLACE TRIGGER [Child_UpdateStatus] FOR UPDATE ON dbo.Child..."); } public override void Down() { Sql("DROP TRIGGER [Child_UpdateStatus]"); } }
Option 2: To keep the field only in Child table and make the Status property computed on Parent entity. 选项2:仅将字段保留在“子”表中,并根据“父”实体计算Status属性。 But I do not know how to get this to work with DataAnnotations or with Fluent API.
但是我不知道如何使它与DataAnnotations或Fluent API一起使用。
[DatabaseGenerated(DatabaseGeneratedOption.Computed)] public int Status { get; private set; }
Option 3: To make NotMapped the property Parent.Status and fill it by code from the Child entity. 选项3:将NotMapped属性设置为Parent.Status并用Child实体中的代码填充它。 This seems the worst solution and it is also hard to maintain and it will not work when the entity is not attached to the context.
这似乎是最糟糕的解决方案,并且也很难维护,并且当实体未附加到上下文时将无法使用。
public class Parent { public int IdParent { get; set; } // ... [NotMapped] public int? Status { get { return this.Intermediate == null ? null : this.parent.Intermediate.Child.Status; } } public Intermediate Intermediate { get; set; } }
I give you a 4th option: override SaveChanges
as follows: 我给您第四个选择:覆盖
SaveChanges
,如下所示:
public partial class MyDbContext : DbContext
{
public override int SaveChanges()
{
try
{
var changeSet = ChangeTracker.Entries<Child>();
if (changeSet != null)
{
foreach (var entry in changeSet.Where(c => c.State == EntityState.Added || c.State == EntityState.Modified))
{
// Update here the parent
}
}
return base.SaveChanges();
}
catch (Exception exception)
{
}
}
}
The idea here is that when you save the changes of your context, you loop over all the entities of type Child
that have been added or modified and then you can properly update the Status
property of your Parent
class 这里的想法是,当您保存上下文的更改时,您可以遍历已添加或修改的
Child
类型的所有实体,然后可以正确更新Parent
类的Status
属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.