通过数据注释的 EF CF 点对点关系

发布于 2024-12-20 06:38:28 字数 1774 浏览 7 评论 0 原文

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

假设我有下表,

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 是来自 Foo 表的外键?

聚苯乙烯

将导航属性声明为 IEnumerable,而不是 ICollection 至关重要。

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

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 更改为 ICollection 的情况下解决此错误,也欢迎。

I want to map a many to may relationship using ONLY data annotations so this is my case.

Say I have the following table

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

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

FooBarRelationships
TheBarId int 
TheFooId int 

As you can see the junction table contains FK names different from source. In addition the name of the table is also different

My classes are as follows

[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; }
}

How should I modify my classes using data annotations in order to tell that the table FooBarRelationships is a junction table and TheBarId is the foreign key from Bar table and TheFooId is the foreign key from Foo table?


P.S.

Having navigation properties declared as IEnumerable<T>, not as ICollection<T> is essential.

I've tried to map it using the map class which looks as follows

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");
            });
    }
}

this gives me the following error.

The type arguments for method 'System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<Bar>.HasMany<TTargetEntity> (System.Linq.Expressions.Expression<System.Func<Bar, ICollection<TTargetEntity>>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

If there is a way to resolve this error without changing the type IEnumeralbe<T> to ICollection<T>, it is also welcomed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

绿萝 2024-12-27 06:38:28

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

EF 4.1 中是否支持 IEnumerable 集合进行映射?

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

最后一部分:

您可以在集合两侧使用 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; }
}

I don't think you ca use IEnumerable because entity framework needs object that can be assigned.

Are IEnumerable collection supported in EF 4.1 for mapping?

You should be attacking the problem from another angle.

last part:

you can use the InverseAttribute on both side of your collection to declare the many to many relationship.

[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; }
}
故事灯 2024-12-27 06:38:28

如果您不使用流畅映射,则必须使用默认约定所需的联结表名称及其列,该名称应类似于: FooBars ,其中包含列 Foo_FooIdBar_BarId

另外,正如 @Inu IEnumerable 的回答中提到的,不支持 - 至少 延迟加载代理需求 ICollection,我几乎确定这是全局要求(如链接答案中所述)。 Code First 通常会跳过映射中的所有 IEnumerable 属性。即使它以某种方式支持 IEnumerable 只是一个接口,后面会有一些类,如 CollectionHashSetList< /code> 因此公开可枚举不会限制使用实体将导航属性转换为该集合类的代码。

If you don't use fluent mapping you must use the name of junction table and its columns expected by default convention which should be something like: FooBars with columns Foo_FooId and Bar_BarId.

Also as mentioned in answer by @Inu IEnumerable is not supported - at least lazy loading proxies demand ICollection and I'm almost sure that it is global requirement (as mentioned in linked answer). Code first normally skips all IEnumerable properties from mapping. Even it it is somehow supported IEnumerable is just an interface and on behind there will be some class like Collection, HashSet or List so exposing enumerable will not restrict code using your entity to convert your navigation property to that collection class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文