当前位置: 首页 > 面试题库 >

父级和子级与自己的类具有相同类型的实体框架代码第一类

萧宣
2023-03-14
问题内容

我有一类Content,应该能够具有用于继承的parentId,但我也希望它具有与该继承树无关的子内容列表。

我基本上想要一个链接表作为ChildContentRelationship,在其中具有id的parentContent和childContent,并且Content类将具有ChildContentRelationship的列表。

这导致了很多错误。

这是我想做的

public class Content
{
    public int Id { get; set; }

    public int? ParentContentId { get; set; }
    public virtual Content ParentContent { get; set; }

    public string Name { get; set; }

    public int ContentTypeId { get; set; }
    public virtual ContentType ContentType { get; set; }

    public virtual ICollection<Property> Properties { get; set; }

    public virtual ICollection<ChildContentRelationship> ChildContent { get; set; } 
}

我将如何在EF中进行设置?


问题答案:

我不确定我是否正确理解您的模型。让我们讨论一下这些选项。

一会儿,我忽略了这个额外的实体,ChildContentRelationship并假设该ChildContent集合是type
ICollection<Content>

  • 选项1:

我认为ParentContent逆属性ChildContent。这意味着如果您有一个Contentwith Id=
x,而此Content有一个ChildContentwith Id=
y,则ChildContentsParentContentId必须始终为x。这仅是单个关联,ParentContent并且ChildContent是该相同关联的端点。

可以使用数据注释创建此关系的映射…

    [InverseProperty("ParentContent")]
public virtual ICollection<Content> ChildContent { get; set; }

…或使用Fluent API:

    modelBuilder.Entity<Content>()
    .HasOptional(c => c.ParentContent)
    .WithMany(c => c.ChildContent)
    .HasForeignKey(c => c.ParentContentId);

我认为这不是您想要的( “ …与…无关”
)。不过,请考虑重命名导航属性。如果有人阅读Parent...并且Child...他很可能会假设他们为相同的关系建立了一对导航属性。

  • 选项2:

ParentContent不是它的inverse属性,ChildContent这意味着您实际上有两个独立的关系,并且两个关系的第二个端点都没有在模型类中公开。

的映射ParentContent如下所示:

    modelBuilder.Entity<Content>()
    .HasOptional(c => c.ParentContent)
    .WithMany()
    .HasForeignKey(c => c.ParentContentId);

WithMany()没有参数表示第二个端点不是模型类中的属性,尤其是 不是 ChildContent

现在,问题仍然存在:ChildContent属于哪种关系?是一对多关系还是多对多关系?

* 选项2a

如果aContent引用其他ChildContents并且不能有第二个Content引用相同的ChildContents(a的子代Content
唯一的 ,可以这么说),那么您就有一对多的关系。(这类似于订单和订单商品之间的关系:一个订单商品只能属于一个特定的订单。)

的映射ChildContent如下所示:

            modelBuilder.Entity<Content>()
        .HasMany(c => c.ChildContent)
        .WithOptional(); // or WithRequired()

Content的数据库表中将具有一个附加的外键列,该列属于该关联,但在实体类中没有对应的FK属性。

* 选项2b

如果许多Content可以引用相同ChildContent的,则您具有多对多关系。(这类似于用户和角色之间的关系:同一角色中可以有许多用户,并且一个用户可以有许多角色。)

的映射ChildContent如下所示:

            modelBuilder.Entity<Content>()
        .HasMany(c => c.ChildContent)
        .WithMany()
        .Map(x =>
        {
            x.MapLeftKey("ParentId");
            x.MapRightKey("ChildId");
            x.ToTable("ChildContentRelationships");
        });

该映射将ChildContentRelationships在数据库中创建一个联接表,但此表不需要相应的实体。

* 选项2c

仅在多对多关系除了两个键(ParentIdChildId)之外具有更多属性的情况下(例如,诸如CreationDateorRelationshipType或…),您才需要ChildContentRelationship在模型中引入一个新实体:

            public class ChildContentRelationship
    {
        [Key, Column(Order = 0)]
        public int ParentId { get; set; }
        [Key, Column(Order = 1)]
        public int ChildId { get; set; }

        public Content Parent { get; set; }
        public Content Child { get; set; }

        public DateTime CreationDate { get; set; }
        public string RelationshipType { get; set; }
    }

现在您的Content班级将有ChildContentRelationships的集合

            public virtual ICollection<ChildContentRelationship> ChildContent
        { get; set; }

您有 两个 一对多的关系:

            modelBuilder.Entity<ChildContentRelationship>()
        .HasRequired(ccr => ccr.Parent)
        .WithMany(c => c.ChildContent)
        .HasForeignKey(ccr => ccr.ParentId);

    modelBuilder.Entity<ChildContentRelationship>()
        .HasRequired(ccr => ccr.Child)
        .WithMany()
        .HasForeignKey(ccr => ccr.ChildId);

我相信您想要选项2a或2b,但是我不确定。



 类似资料:
  • 我有两个从抽象类继承的类,它们有父子关系。 所以我使用了注释OneToOne和ManyToOne,但是子类中的父实体总是为空。有人能帮我吗,我花了几个小时谷歌和测试了许多conf,但没有成功。 这些是我的类中的代码: ... ... ... 如果我不添加@JoinCol列注释,JPA会创建一个关联表,但无法检索父级,而关联可以直接通过在数据库中请求来完成。 非常感谢你的帮助。 祝好

  • 问题内容: 我有下表: 我想让Folder类具有父子关系。 问题答案: 我相信正确的映射将是: 该会的工作只有当每个家长有最多一个孩子,上面的代码适用于更一般的情况下,父母可以有许多儿童。另外,为简单起见,我省略了get / set方法。

  • 问题内容: 考虑以下类: 由于多个的声明,in 的声明不应该给出编译错误吗? 问题答案: 阴影 (或 隐藏物 )。 这是合法的Java,但应避免使用。我希望您的IDE可以为您提供警告。 但是请注意,这只是一个问题,因为您已经向世界公开了一个 变量 。如果确保所有变量都是私有变量(将方法的API与字段的实现分开),那么父级和子级都具有相同的字段名就没关系- 子级不会仍然能够看到父母的字段。如果将方法

  • 如何修复错误... 更新记录显示此错误时: 显示错误:{“附加“DomainClass.WorkshopReport”类型的实体失败,因为相同类型的另一个实体已具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“Attach”方法或将实体状态设置为“Unchanged”或“Modified”时可能会发生这种情况。这可能是因为某些实体是新实体,尚未收到生成的数据库关键值。在这种情况下,请使

  • 我试图在我的实体中有两个相同域类的字段,但我得到了这个错误: org.hibernate.mappingException:无法确定表:Outhories中:com.packt.webapp.domain.user的类型,列:[org.hibernate.mapping.column(author)] 我只想将意见映射到已评论的用户,并将评论的作者存储在字段中。当我移除字段时,一切正常。这个例子有

  • 让我快速描述一下我的问题。 我有5个客户的5个数据库,每个数据库都有一个名为SubnetSettings的表。 我已经创建了一个下拉列表来选择一个客户,并将显示属于所选客户的SubnetSSet表,并允许我创建、编辑和删除。 我可以毫无问题地创建、删除,但当我想编辑数据时,它会带来错误: /运输管理系统应用程序中的服务器错误。 附加“CFS”类型的实体。领域实体。SubnetSettings“失败