【问题标题】:Entity Framework and many-to-many relation with explicit link table实体框架和与显式链接表的多对多关系
【发布时间】:2013-05-06 19:09:50
【问题描述】:

我正在使用代码优先的实体框架,我知道您可以通过向每个对象添加一个 ICollection,轻松地在 ObjectA 和 ObjectB 之间创建多对多关系; EF 会在后台自动创建链接表。

public class ObjectA {
    public ICollection<ObjectB> ObjectsB { get; set; }
}

public class ObjectB {
    public ICollection<ObjectA> ObjectsA { get; set; }
}

现在我需要这个关系的附加属性,所以我制作了自己的链接表

public class ObjectA {
    public ICollection<ObjectA_ObjectB> AtoB { get; set; }
}

public class ObjectB {
    public ICollection<ObjectA_ObjectB> BtoA { get; set; }
}

public class ObjectA_ObjectB {
    public ObjectA A { get; set; }
    public ObjectB B { get; set; }

    public DateTime MyStartDate { get; set; }
}

这很好用,但最大的损失是我现在在我的实体中不再有 ObjectB 和 ObjectA 的直接集合,即使关系仍然相同,只是有一个显式链接表。

我真的很想找回我的直接收藏。有什么方法(使用模型构建器或数据注释?)将上述两种方法结合起来?

【问题讨论】:

    标签: entity-framework many-to-many code-first


    【解决方案1】:

    不,没有办法将原始集合作为导航属性。您可以做的是添加未映射到数据库并且是只读的帮助器集合:

    public class ObjectA {
        public ICollection<ObjectA_ObjectB> AtoB { get; set; }
    
        public IEnumerable<ObjectB> ObjectsB
        {
            get { return AtoB.Select(ab => ab.B); }
        }
    }
    

    加载AtoB 的查询会给你想要的结果:

    var objectA = context.ObjectAs
        .Include(a => a.AtoB.Select(ab => ab.B)).First();
    
    // objectA.ObjectsB would return the Bs now
    

    但它相当有限,因为您不能在任何查询中使用此集合,也不能通过此集合操作关系。为此,您始终必须使用 AToB 集合。

    【讨论】:

    • 这对我的目标非常有效。我只需要将 [NotMapped] 数据注释添加到我的帮助器集合中,否则 EF 会因 Sqlexception “Invalid column name 'ObjectB_Id'”而窒息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    相关资源
    最近更新 更多