EF Code First 不返回相关对象
我正在将 EF Code First 与预先存在的数据库结合使用。
两个对象:
public Foo
{
public int FooId {get;set;}
}
public Bar
{
public int BarId {get;set;}
public virtual Foo Foo {get;set;}
}
FooId
和 BarId
都是数据库中的主键,Bar
表有一列 FooId
这是指向 Foo
表的外键。
当我选择 Bar
时,Foo
是空引用。我本以为 EF 会自动将两者拉到一起,但也许我错过了一些东西?
数据库映射:
public class EFCodeFirst : DbContext
{
public EFCodeFirst()
{
this.Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["AlternateString"].ConnectionString;
}
public DBSet<Foo> Foos {get;set;}
public DBSet<Bar> Bars {get;set;}
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
modelBuilder.IncludeMetadataInDatabase = false;
modelBuilder.Entity<Foo>().MapSingleType().ToTable("Foo");
modelBuilder.Entity<Bar>().MapSingleType().ToTable("Bar");
}
}
I'm using EF Code First with a pre-existing database.
Two objects:
public Foo
{
public int FooId {get;set;}
}
public Bar
{
public int BarId {get;set;}
public virtual Foo Foo {get;set;}
}
Both FooId
and BarId
are primary keys in the database, and the Bar
table has a column FooId
which is a foreign key pointing at the Foo
table.
When I select a Bar
, Foo
is a null reference. I would have thought EF would have automatically pulled the two of them together, but perhaps I'm missing something?
Database mappings:
public class EFCodeFirst : DbContext
{
public EFCodeFirst()
{
this.Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["AlternateString"].ConnectionString;
}
public DBSet<Foo> Foos {get;set;}
public DBSet<Bar> Bars {get;set;}
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
modelBuilder.IncludeMetadataInDatabase = false;
modelBuilder.Entity<Foo>().MapSingleType().ToTable("Foo");
modelBuilder.Entity<Bar>().MapSingleType().ToTable("Bar");
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您对 Foo 的期望不应该为 null 是因为您在 Bar 对象上将其设为虚拟的,那么情况并非如此。通过将它们设为虚拟,您只需选择 EF 延迟加载,直到您通过在 Bar 对象上访问它来明确请求它为止,它将为空。除此之外,如果您希望预先填充它,则必须使用 Include 方法急切地加载它。
要显式禁用延迟加载,您可以使用以下代码,即使您不需要它,因为您只需从导航属性中删除virtual关键字,延迟加载就会消失。
在内部,DbContext 使用受保护的 ObjectContext,您也可以在继承的 DbContext 类(例如 EFCodeFirst)中使用它。
If your expectation of Foo should not be null is coming from the fact that you make it virtual on Bar object, then that's not the case. By make them virtual, you just opt in to EF lazy loading and it will be null up until to the point that you explicitly ask for it by accessing it on Bar object. Other than that, if you want it to be populated upfront you would have to eager load it with Include method.
To explicitly disable lazy loading you can use the following code, even though you don't need it since you can just remove the virtual keyword from your navigation properties and lazy loading would be gone.
Internally, DbContext uses a protected ObjectContext that you can also use inside your inherited DbContext class (e.g. EFCodeFirst).
您在 Foo 类中缺少一行,即 Foo 包含 Bar 的集合。
You are missing a line in the Foo class, that Foo contains a collection of Bar.