cul*_*oly 6 .net c# sql-server entity-framework relational-database
对于精通EF的用户来说,这应该是一个简单的问题.
我有以下模式(在我的脑海中)表示表之间的关系应该如何.
[FooBar] [Foo] [Bar]
FooId PK,FK Id PK Id PK
BarId PK,FK BarId FK Name
IsRead Name Description
Description
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用EF代码生成模式时,首先它无法解释实体之间的关系,因为我已解释它们(FooId
向[bar]
表中添加外键)并且无法完全创建[FooBar]
桥表.
如果有人可以指导我如何使用EF4代码实现上述架构 - 首先我很感激.只要创建了所需的数据库模式,解决方案是否涉及我的POCO模型上的属性,流畅的配置或两者的混合都无关紧要.
POCO型号:
public class Foo
{
public int Id { get; set; }
public string Text { get; set; }
public string Description { get; set; }
public int BarId { get; set; }
public Bar Bar { get; set; } /* bar entity */
public virtual ICollection<Bar> BridgedBars { get; set; }
public Foo()
{
Bars = new List<Bar>();
}
}
public class Bar
{
public int Id { get; set; }
public string Text { get; set; }
public string Description { get; set; }
public virtual ICollection<Foo> Foos { get; set; }
public virtual ICollection<Foo> BridgedFoos { get; set; }
public Bar()
{
Foos = new List<Foo>();
BridgedFoos = new List<Foo>();
}
}
public class FooBar
{
public int FooId { get; set; }
public int BarId { get; set; }
public virtual Foo Foo { get; set; }
public virtual Bar Bar { get; set; }
public bool IsRead { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
您的模型确实将创建一个外键FooId
在Bar
属于由定义的关系Foo.BrideBars
.EF不会将此导航属性与其中一个ICollection<Foo>
属性相关联,Bar
因为它们中有两个并且EF无法唯一地确定哪个是正确的对.因此,它Foo.BrideBars
在另一端创建了没有导航属性的关系.可以这么说,有一个不可见的Bar.Foo
属性导致外键.
要映射到模型的数据库模式实际上并不代表多对多关系,而是与中间"桥"实体的两个一对多关系FooBar
.您必须在导航属性中使用此类来定义正确的关系.它看起来像这样:
public class Foo
{
public int Id { get; set; }
public string Text { get; set; }
public string Description { get; set; }
public int BarId { get; set; }
public Bar Bar { get; set; }
public virtual ICollection<FooBar> FooBars { get; set; }
}
public class Bar
{
public int Id { get; set; }
public string Text { get; set; }
public string Description { get; set; }
public virtual ICollection<Foo> Foos { get; set; }
public virtual ICollection<FooBar> FooBars { get; set; }
}
public class FooBar
{
[Key, Column(Order = 0)]
public int FooId { get; set; }
[Key, Column(Order = 1)]
public int BarId { get; set; }
public virtual Foo Foo { get; set; }
public virtual Bar Bar { get; set; }
public bool IsRead { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
将通过此模型中的命名约定检测正确的关系.仅对于FooBar
实体,必须明确定义键,因为属性名称不符合约定(no Id
和no FooBarId
属性).在这个模型中,使用复合键是有意义的FooBar
.
我想,你的真正的类和属性没有名称Foo
和Bar
.如果您的真实姓名不遵循惯例,则可能需要指定与注释的关系 - 或使用Fluent API:
modelBuilder.Entity<Foo>()
.HasRequired(f => f.Bar)
.WithMany(b => b.Foos)
.HasForeignKey(f => f.BarId);
modelBuilder.Entity<FooBar>()
.HasKey(fb => new { fb.FooId, fb.BarId }); // replaces the [Key] annotations
modelBuilder.Entity<FooBar>()
.HasRequired(fb => fb.Foo)
.WithMany(f => f.FooBars)
.HasForeignKey(fb => fb.FooId);
modelBuilder.Entity<FooBar>()
.HasRequired(fb => fb.Bar)
.WithMany(b => b.FooBars)
.HasForeignKey(fb => fb.BarId);
Run Code Online (Sandbox Code Playgroud)
在您的数据库模式中,该FooBar
表将具有复合主键:
[FooBar] [Foo] [Bar]
FooId PK,FK Id PK Id PK
BarId PK,FK BarId FK Name
IsRead Name Description
Description
Run Code Online (Sandbox Code Playgroud)
但是必须拥有PK,FooBar
因为EF模型中的每个实体都必须定义一个键属性 - 单个或复合 - 映射到数据库表中的主键.
在这个问题中 - 首先创建代码,多对多,以及关联表中的其他字段 - 更详细地说明如何使用这种类型的关系.(有时人们也称之为" 与有效载荷的多对多关系"(该IsRead
属性是示例模型中的"有效载荷"),但事实上它并不是多对多的.)
归档时间: |
|
查看次数: |
6769 次 |
最近记录: |