简体   繁体   English

如何在父实体中拥有一个属性,该父实体的值属于子实体,而EF6和Code-First则将其下两层

[英]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.

相关问题 EF代码优先如何使用Entity检索导航属性? - EF code-first how to retrieve navigation-property with Entity? 在EF4代码优先中,如何使一个实体的主键成为另一个实体? - How can I have the primary key of one entity be another entity in EF4 code-first? 使用EF6 Store Functions for Entity Framework代码优先,我可以返回自定义类型吗? - Using EF6 Store Functions for Entity Framework code-first, can I return a custom type? 如何使用EF6 Code First将外键属性公开给具有导航属性的现有实体 - How to expose Foreign Key property to existing entity having navigational property using EF6 Code First 如何在 EF6 Database-First 中为所有实体类拥有一个未映射的公共抽象 BaseEntity 父级? - How to have a not mapped, common abstract BaseEntity parent for all entity class in EF6 Database-First? EF代码优先:如何将两个实体的数据保存在一个表中? - EF code-first: how to save two entity's data in one table? 使用EF6代码优先,引用相同的属性名称 - Using EF6 code-first, reference same property name EF6代码优先:具有多个关系的实体 - EF6 Code First : Entity with multiple relationships 代码优先EF6-如何转换为不是实体的自定义对象 - Code First EF6 - How to translate to a custom object thats not an entity 代码优先-按键获取子实体 - Code-first - get child entity by key
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM