Entity Framework多个外键到同一个表

时间:2015-01-19 20:25:47

标签: c# entity-framework

我有两个实体DataTag和CalcDataTag:

public class CalcDataTag : BaseModel
{
    [Column("CalcDataTagId")]
    public override Guid ID { get; set; }

    public Guid DataTagId { get; set; }
    public DataTag DataTag { get; set; }

    public Guid ChildDataTagId { get; set; }
    public DataTag ChildDataTag { get; set; }
}

public class DataTag : BaseModel
{
    [Column("DataTagId")]
    public override Guid ID { get; set; }

    public ICollection<CalcDataTag> CalcDataTags { get; set; }
}

我像这样设置上下文:

modelBuilder.Entity<DataTag>()
            .HasMany<CalcDataTag>(x => x.CalcDataTags)
            .WithRequired(x => x.ChildDataTag)
            .HasForeignKey(x => x.ChildDataTagId);

        modelBuilder.Entity<DataTag>()
            .HasMany<CalcDataTag>(x => x.CalcDataTags)
            .WithRequired(x => x.DataTag)
            .HasForeignKey(x => x.DataTagId);

CalcDataTags列表应该是CalcDataTags列表,其中DataTagId或ChildDataTagId等于DataTag的ID,但是设置上下文的方式,底部设置会覆盖顶部设置,我只获得CalcDataTags列表,其中DataTagId等于DataTag的ID。如果我切换设置,那么我只得到一个CalcDataTags列表,其中ChildCalcDataTagId等于DataTag的ID。基本上我想要得到的是两个列表的联合。每个实体只有一个PrimaryKey,没有复合键。

1 个答案:

答案 0 :(得分:2)

您需要在DataTag表格上设置第二个集合。除此之外别无他法。实体框架变得混乱,因为它只能将一对多关系映射到特定属性,而不是两个。您需要执行以下操作:

DataTag

public ICollection<CalcDataTag> CalcDataTags { get; set; }
public ICollection<CalcDataTag> ChildCalcDataTags { get; set; }

modelBuilder

modelBuilder.Entity<DataTag>()
            .HasMany<CalcDataTag>(x => x.ChildCalcDataTags)
            .WithRequired(x => x.ChildDataTag)
            .HasForeignKey(x => x.ChildDataTagId);

modelBuilder.Entity<DataTag>()
            .HasMany<CalcDataTag>(x => x.CalcDataTags)
            .WithRequired(x => x.DataTag)
            .HasForeignKey(x => x.DataTagId);

如果您希望能够同时抓取所有这些内容(就像您看到的那样),您可能需要考虑添加一个[NotMapped]属性来获取两个集合的并集,如此:

[NotMapped]
public ICollection<CalcDataTag> AllCalcDataTags
{
  return CalcDataTags.Union(ChildCalcDataTags);
}