为什么EF Code First中的外键标记为虚拟?

时间:2016-11-21 20:51:45

标签: entity-framework ef-code-first

public virtual Student Student {get; set;}

为什么需要将外键约束标记为虚拟?我见过虚拟和缺乏虚拟的例子。这有关系吗?

1 个答案:

答案 0 :(得分:3)

通过查看:https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx,以及@Shoes在评论中提供的链接。

我会这样说:

<强> 1。如果你宣布你的财产是虚拟的:

查询主对象时,不会立即加载您的虚拟属性(默认情况下)。只有当您尝试访问它或访问其中一个组件时,它才会从数据库中进行检索。

这称为延迟加载。

<强> 2。如果你声明它是非虚拟的:

您的财产将(默认情况下)立即加载到您的主要实体中的所有其他财产。这意味着您的财产将可以访问:它已经被检索。实体不必再次查询数据库,因为您访问此属性。

这称为急切加载。

我的观点:

我经常选择急切加载(非虚拟),因为大多数时候,我需要使用每个实体的每个属性而不必回复(如果你真的想要快速的话,请更快)但是如果你偶尔访问此属性一次(您没有列出任何内容),并且您希望更多地通常只有其余信息执行此操作,然后将其设置为虚拟,以便此属性不会减慢查询的其余部分仅为少数访问。

希望这很清楚......

例子:

我不会使用虚拟(热切):

foreach(var line in query)
{
    var v = line.NotVirtual; // I access the property for every line
}

我将使用虚拟或延迟加载:

foreach(var line in query)
{
    if(line.ID == 509)        // because of this condition
    var v = line.Virtual; // I access the property only once in a while
}

最后一件事:

如果您不查询超过1 000行数据库,那么您选择的任何内容都不会产生很大影响。此外,您可以将这些属性声明为虚拟,如果您想要反过来测试,则只需执行此操作(实体4.0):

context.LazyLoadingEnabled = false;

它将取消虚拟效果。

修改

对于较新版本的EF:

WhateverEntities db = new WhateverEntities() 
db.Configuration.LazyLoadingEnabled = false;