Dav*_*Dav 17 .net mapping entity-relationship entity-framework code-first
<RANT_MODE>
EF代码优先方法意味着节省大量时间,但暂时我只看到玩具示例,并花了几个小时试图了解如何使它生成我想要的数据库.但仍然希望尤里卡时刻:-)
<RANT_MODE />
关于问题!
我试图了解EF如何映射和检索对象关系.什么时候我应该标记一个属性virtual?(public Person Owner { get; set; }与对比一样public virtual Person Owner { get; set; }.)在代码优先的几十个例子中,我看到他们似乎可以互换地使用这些,而没有太多的解释.我所知道的是导航属性(public virtual ICollection<Person> Owners { get; set; })需要是virtual为了使延迟加载成为可能(正确...?),但这在非集合的世界中如何应用?
public int OwnerId { get; set; }除了我感兴趣的'main'属性之外,我无法找到关于是否应该包含外键字段()的任何信息public Person Owner { get; set; }.我试着不这样做,EF亲切地自动添加了一个Owner_Id在我的表中命名的int列,似乎理解了我的意图.
在Code First的约定("外键"部分)中,EF团队提到"在关系的依赖端包含外键属性是很常见的",并且"Code First现在将推断任何名为''的属性(即OwnerId)[...]与主键具有相同的数据类型,表示关系的外键".IE浏览器.如果我有两个EF将知道他们是相关的.
但除了"异物"本身之外,明确指定持有FK的此类属性是否被视为良好做法?
正如我上面提到的,即使我只public Person Owner { get; set; }在我的对象中(例如Event),该表Events将包含Owner_Id由EF自动添加的列.更重要的是,在检索时,我将可以访问属性Owner.
但是,请考虑以下方案.我有两节课:
public class Account
{
public int Id { get; set; }
public Person Owner { get; set; }
}
public class OpenIdAccount : Account
{
public string Identifier { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我希望他们与TPT有关.这意味着手动映射:
modelBuilder.Entity<Account>().MapHierarchy(a => new
{
a.Id,
Owner_Id = a.Owner.Id
}).ToTable("Account");
modelBuilder.Entity<OpenIdAccount>().MapHierarchy(a => new
{
a.Id,
a.Identifier
}).ToTable("OpenIdAccount");
Run Code Online (Sandbox Code Playgroud)
您可能会注意到,我尝试重新创建EF对我的Owner_Id列所做的事情.但在检索时,myAccountInstanceFromDb.Owner为空.这是为什么?我怎么告诉EF它应该发挥它的魔力并填充我的Owner财产?
如果你能澄清上述内容,我将非常感激 - 到了真正希望知道答案的地步,但又无法阅读另一篇仅仅展示另一个玩具的例子,说明与EF一起玩是多么容易.也就是说,如果你对EF的大脑有一个深入的最新参考,请发布链接.
提前谢谢您的时间!
这与代码首先无关,它是EF和POCO的主题:当您拥有POCO时,您会失去对导航属性的大量EF支持,您可以通过将它们设置为虚拟来选择加入它们.这使EF可以在运行时创建代理,并通过覆盖该代理类中的导航属性来为您提供支持.这些支持是更改通知,关系修复和延迟加载.
延迟加载对Collection和非Collection类型导航属性的工作方式相同.此外,始终将导航属性标记为虚拟也是一种很好的做法.
EF3.5不支持关联中的FK并使它们隐藏(也称为独立关联).EF4开始支持协会中的FK(又名外键协会).取决于您喜欢哪一个,您可以明确包含或不包含FK属性,但除了导航属性之外,明确指定FK属性绝对是一个好习惯,因为它为您提供了使用对象的最大灵活性.
检索后,myAccountInstanceFromDb.Owner为null.这是为什么?我怎么告诉EF它应该做它的魔术并填充我的所有者属性?
当然,您没有将其标记为虚拟,因此不支持延迟加载,但您没有明确地急切加载或延迟加载它.要解决这个问题,要么使用虚拟关键字,让EF懒惰加载它,或者使用Include方法在整个对象实现时急切加载它.
标量属性是属性,其值实际上包含在实体中并与表列对应(例如Account.Id).
导航属性仅是指向相关实体的指针.例如,Account实体具有Owner属性,该属性将使应用程序能够从Account导航到拥有该Account的所有者.
所以,回到你的问题,你需要做的就是指定一个导航属性,virtual Person Owner并可选择指定一个FK属性int OwnerId,你很高兴.
| 归档时间: |
|
| 查看次数: |
2431 次 |
| 最近记录: |