【问题标题】:EF CF m-to-n relationship via data annotations通过数据注释的 EF CF m-to-n 关系
【发布时间】:2011-12-09 08:28:40
【问题描述】:

我想仅使用数据注释来映射多对可能的关系,所以这是我的情况。

假设我有下表

Foo:
FooId int identity
FooName varchar(max) not null

Bar:
BarId int identity
BarName varchar(max) not null

FooBarRelationships
TheBarId int 
TheFooId int 

如您所见,联结表包含与源不同的 FK 名称。另外表名也不同

我的课如下

[Table("Foo")]
public class Foo {
    [Key]
    public Int32 FooId { get; set; }
    public String FooName { get; set; }

    public IEnumerable<Bar> Bars { get; set; }
}

[Table("Bar")]
public class Bar { 
    [Key]
    public Int32 BarId { get; set; }
    public String BarName { get; set; }

    public IEnumerable<Foo> Foos { get; set; }
}

我应该如何使用数据注释修改我的类,以便告诉表 FooBarRelationships 是联结表,TheBarId 是来自 Bar 表的外键,TheFooId 是来自 @987654327 的外键@桌子?

附言

将导航属性声明为IEnumerable&lt;T&gt;,而不是ICollection&lt;T&gt; 是必不可少的。

我尝试使用如下所示的地图类对其进行映射

public class BarMap : EntityTypeConfiguration<Bar> {
    public BarMap() {
        this.HasMany(t => t.Foos)
            .WithMany(t => t.Bars)
            .Map(m => {
                m.ToTable("FooBarRelationships");
                m.MapLeftKey("TheBarId");
                m.MapRightKey("TheFooId");
            });
    }
}

这给了我以下错误。

方法 'System.Data.Entity.ModelConfiguration.EntityTypeConfiguration.HasMany (System.Linq.Expressions.Expression>>)' 的类型参数不能从用法推断。尝试明确指定类型参数。

如果有办法在不将类型IEnumeralbe&lt;T&gt; 更改为ICollection&lt;T&gt; 的情况下解决此错误,也欢迎。

【问题讨论】:

    标签: c# entity-framework-4.1 many-to-many data-annotations code-first


    【解决方案1】:

    我认为您不能使用 IEnumerable,因为实体框架需要可以分配的对象。

    Are IEnumerable collection supported in EF 4.1 for mapping?

    你应该从另一个角度解决问题。

    最后一部分:

    您可以使用集合两侧的 InverseAttribute 来声明多对多关系。

    [Table("Foo")]
    public class Foo {
        [Key]
        public Int32 FooId { get; set; }
        public String FooName { get; set; }
        [InverseAttribute("Foos")]
        public ICollection<Bar> Bars { get; set; }
    }
    
    [Table("Bar")]
    public class Bar { 
        [Key]
        public Int32 BarId { get; set; }
        public String BarName { get; set; }
        [InverseAttribute("Bars")]
        public ICollection<Foo> Foos { get; set; }
    }
    

    【讨论】:

    • 感谢您的回复。我恢复了 ICollection 并以不破坏内涵的方式重新组织了解决方案。你能回答问题的第一部分,关于在不使用 fluent api 的情况下提供表元数据,只使用数据注释吗?
    【解决方案2】:

    如果您不使用流利映射,则必须使用连接表的名称及其列,默认约定应类似于:FooBars,列Foo_FooIdBar_BarId

    正如@Inu IEnumerable 的回答中提到的那样,不支持 - 至少 lazy loading proxies demand ICollection 我几乎可以肯定这是全球要求(如链接答案中所述)。代码首先通常会跳过映射中的所有 IEnumerable 属性。即使它以某种方式受到支持 IEnumerable 只是一个接口,后面会有一些类,如 CollectionHashSetList 因此公开可枚举不会限制代码使用您的实体将您的导航属性转换为集合类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-05
      • 2011-07-30
      • 2020-12-06
      • 2016-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多