< RANT_MODE >
EF 代码优先方法旨在节省大量时间,但目前我只看到玩具示例并花费数小时试图了解如何使其生成我想要的数据库。但仍然希望尤里卡时刻:-)
< RANT_MODE />
关于问题!
虚拟与具体属性
我试图了解 EF 如何映射和检索对象关系。我应该什么时候标记一个属性virtual
,什么时候不?(如在public Person Owner { get; set; }
vs.中public virtual Person Owner { get; set; }
。)在我见过的数十个代码优先示例中,他们似乎可以互换使用这些示例,但没有太多解释。我所知道的是导航属性 ( public virtual ICollection<Person> Owners { get; set; }
) 必须是virtual
为了使延迟加载成为可能(正确..?),但这在非收藏品世界中如何应用?
对象关系和外键
public int OwnerId { get; set; }
除了我感兴趣的“主要”属性()之外,我找不到任何关于是否应该包含外键字段( )的信息public Person Owner { get; set; }
。我尝试不这样做,并且 EF 友好地自动添加了一个 int 列Owner_Id
在我的表中命名,似乎理解我想要实现的目标。
在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; }
}
我希望它们与 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");
您可能会注意到,我试图重新创建 EF 对我的Owner_Id
专栏所做的事情。然而在检索时,myAccountInstanceFromDb.Owner
为空。这是为什么?我如何告诉 EF 它应该发挥它的魔力并填充我的Owner
财产?
指针,指针
如果您能澄清上述内容,我将不胜感激 - 达到了真正希望知道答案的地步,但无法阅读另一篇文章,该文章仅展示了另一个玩具示例,说明使用 EF 是多么容易。也就是说,如果您确实对 EF 的大脑有深入的最新参考,请也发布链接。
提前感谢您的宝贵时间!