假设我有以下数据库表,其中包含1:1映射
Table dbo.Foo with PrimaryKey FooRowId
Table dbo.Bar with PrimaryKey BarRowId
两个表都没有外键。
使用EF,我将模型定义如下。
建模Foo表
public class Foo
{
[Key]
public long FooRowId { get; set; }
// Navigation
public virtual Bar Bar { get; set; }
}
建模栏表
public class Bar
{
[Key]
public long BarRowId { get; set; }
// Navigation
public virtual Foo Foo { get; set; }
}
这给了我与导航属性相关的错误如下。
无法确定类型'MyOrg.Models.Foo'之间关联的主要结尾 和'MyOrg.Models.Bar'。这种关联的主要目的必须明确 使用关系流畅的API或数据注释进行配置。
解决方法之一是通过标准化属性名称,如下所示。
On Foo
public class Foo
{
[Key]
[Column("FooRowId")]
public long FooId { get; set; }
// Navigation
public virtual Bar Bar { get; set; }
}
在栏上
public class Bar
{
[Key]
[Column("BarRowId")]
public long BarId { get; set; }
// Navigation
public virtual Foo Foo { get; set; }
}
但是,要求声明我必须保留原始属性FooRowID
和BarRowId
。鉴于此约束,如何使导航属性有效?
答案 0 :(得分:1)
尽管属性看起来很容易使用,但它限制了在其他数据库中重用类。
假设您已根据公司的标准(国家/地区)创建了类BillingAddress。您希望在两个不同的DbContexts中使用此类,每个DbContexts代表它们自己的数据库。数据库1中的BillingAddress在列" MyPrimaryKey"中具有主键,数据库2中的BillingAddress在列" Id"中具有主键。你无法使用属性来解决这个问题。
列和表的名称,表之间的关系是数据库的一部分。因此,这应该在DbContext中描述。如果您不在DbSet类中使用Attributes,那么您将能够在不同的数据库中使用相同的类。
所以让我们用流利的Api写你的桌面设计
请参阅:
下面我举例说明所有三个类别:
请记住:如果您首先使用代码,并坚持the entity framework code first conventions,则不需要这些代码。只要你坚持这些约定,Entity Framework就能非常有能力检测主键,外键,表之间的关系。
但是如果你的表不同,你的DbContext中需要以下流畅的API
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configure entity table FOO:
var entityFoo = modelBuilder.Entity<Foo>();
// example: configure Name and primary key of foo table
entityFoo.ToTable("MySpecialFooTable");
entifyFoo.HasKey(foo => foo.FooRowId);
// example: configure property Name is in column FooName:
entityFoo.Property(foo => foo.Name).HasColumnName("MyFooName");
// example: one-to-many relation between foo and bar
// every Foo has zero or more Bars in property MyBars,
// every Bar belongs to exactly one For in property MyFoo
// using foreign key MyFooId:
entityFoo.HasMany(foo => foo.MyBars) // Foo has zero or more Bars in MyBars
.WithRequired(bar => bar.MyFoo) // every Bar belongs to one Foo
.HasForeignKey(bar => bar.MyFooId); // using foreign key MyFooId
}