通过数据注释实现EF CF m-to-n关系

时间:2011-12-09 08:28:41

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

我想使用ONLY数据注释来映射多个to may关系,所以这是我的情况。

说我有下表

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表和{{1}的外键}是来自TheFooId表的外键吗?

附:

将导航属性声明为Foo,而不是IEnumerable<T>是必不可少的。

我尝试使用地图类映射它,如下所示

ICollection<T>

这给了我以下错误。

  

方法'System.Data.Entity.ModelConfiguration.EntityTypeConfiguration&lt; Bar&gt; .HasMany&lt; TTargetEntity&gt;的类型参数(System.Linq.Expressions.Expression&lt; System.Func&lt; Bar,ICollection&lt; TTargetEntity&gt;&gt;&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"); }); } } 更改为IEnumeralbe<T>,也欢迎使用。

2 个答案:

答案 0 :(得分: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; }
}

答案 1 :(得分:1)

如果不使用流畅映射,则必须使用默认约定所期望的联结表及其列的名称,其类似于:FooBars,列Foo_FooIdBar_BarId

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