首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将两个属性一对多映射到同一集合

将两个属性一对多映射到同一集合
EN

Stack Overflow用户
提问于 2012-07-09 23:23:11
回答 1查看 444关注 0票数 3

我首先使用Entity Framework4.3代码。如何在类A中的两个属性和类B中的集合之间创建两个“一对多”-relationships?

我的模型:

代码语言:javascript
复制
public class Shaft
{
    public int Id { get; set; }

    public virtual Coupling FirstEnd { get; set; }
    public virtual Coupling SecondEnd { get; set; }
}

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

    public virtual ICollection<Shaft> Shafts { get; set; }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-10 05:01:52

一对多关系被称为one-to- of,因为在关系的第一端有one元素,在另一端有许多元素。您还可以有一个零或一个对多的关系,这只意味着不多的一端的元素可以是null (或数据库中的NULL )。

您正在尝试定义的是两个对多(或者可能是零、一对多或两个对多)关系。这样的东西既不存在于关系数据库中,也不存在于实体框架中。

当您定义与EF的关系时,您总是需要源和目标类中两个导航属性的。可以省略其中一个导航属性,但这并不意味着您可以将此关系的末端移动到已经属于另一个关系的另一个导航属性。

在您的特定情况下,您有两个关系,因为您的两个导航属性FirstEndShaft中的SecondEnd表示两个不同的外键。因此,您可以在Coupling中使用两个集合,也可以将现有属性Coupling.ShaftsFirstEndSecondEnd关联,但不能同时与这两个属性关联。另一个引用将引用Coupling中未公开的“不可见”导航集合。(这是您自己答案中的映射将发生的情况: EF将采用覆盖第一个映射块的第二个映射块,创建SecondEndShafts之间的关系,然后FirstEnd和未公开的关系之间的另一个关系以Coupling结束,而不是再次以Shafts结束。)

有两个集合的解决方案--在我看来更有意义--应该是这样的:

代码语言:javascript
复制
public class Coupling
{
    public int Id { get; set; }

    public virtual ICollection<Shaft> ShaftsWithFirstEndHere { get; set; }
    public virtual ICollection<Shaft> ShaftsWithSecondEndHere { get; set; }
}

和这个映射:

代码语言:javascript
复制
modelBuilder.Entity<Coupling>()
    .HasMany(x => x.ShaftsWithFirstEndHere)
    .WithOptional(x => x.FirstEnd);

modelBuilder.Entity<Coupling>()
    .HasMany(x => x.ShaftsWithSecondEndHere)
    .WithOptional(x => x.SecondEnd);

您可以创建一个只读且未映射的帮助器属性,以将两个集合连接到一个集合,但此连接将在两个导航集合加载后在内存中发生:

代码语言:javascript
复制
public class Coupling
{
    public int Id { get; set; }

    public virtual ICollection<Shaft> ShaftsWithFirstEndHere { get; set; }
    public virtual ICollection<Shaft> ShaftsWithSecondEndHere { get; set; }

    // not mapped to DB because it has only a getter = readonly
    public IEnumerable<Shaft> Shafts
    {
        get { return ShaftsWithFirstEndHere.Concat(ShaftsWithSecondEndHere); }
    }
}

没有一种映射可以自动完成这样的连接。请注意,一对多关系中的导航集合属性只是通过依赖表中的外键进行查询的结果(在您的示例中为= Shaft )。用于填充集合的外键(例如,通过使用Include或当延迟加载被触发时)由关系映射很好地定义,并且它只有一个键-要么是FirstEnd的键,要么是SecondEnd的键,但不能同时存在。您正在尝试实现的是两个不同外键的两个查询的组合连接结果。而这在关系映射中是不可能的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11398142

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档