2

在观看一些实体框架教程时,我发现有很多方法可以在两个实体之间创建关系。但是我很难理解这些行的确切含义。

public virtual Person person { set; get; }

public virtual IEnumerable<Person> person { set; get; }

public virtual ICollection<Person> person { set; get; }

在其中一个视频中,他们解释说,当您同时创建一个虚拟属性时,ICollection这会启用延迟加载

在这种情况下,virtual 关键字会做什么?如果我们在没有 virtual 关键字的情况下尝试这样做会发生什么?

4

2 回答 2

3

EF 需要将这些类实现为虚拟类,因为代理是在运行时作为继承类创建的。延迟加载引擎所做的是在后台重新实现(覆盖这些属性以按预期工作。virtual关键字正是这样做的:允许其他类覆盖它的实现。如果您希望启用延迟加载并正常工作,这基本上就是您需要这些虚拟属性的原因。

您会注意到,当启用延迟加载时,您在运行时获得的实例名称很奇怪,例如“Person_Proxy987321654697987465449”。

关于关系,每当您在数据库中创建一个具有例如 1:N 关系的实体时,您都可以拥有一个 EF 自动列出其关系的集合,因此您可以像本示例一样在代码中使用它,假设“Person 1 :N 订单":

var ordersFromSomePerson = person.Orders;

于 2013-07-10T16:05:39.663 回答
0

为了回答虚拟 ICollection为什么在 EF 中启用延迟加载的问题,我们需要 C# 中virtual关键字的定义和含义。来自MSDN

The virtual keyword is used to modify a method, property, indexer or event declaration, 
and allow it to be overridden in a derived class. For example, this method can be 
overridden by any class that inherits it.

它是面向对象编程概念的继承机制的一部分。

通常情况下,子类需要另一个(扩展)功能作为基类。在这种情况下,virtual关键字允许程序员重写(如果需要,此当前实现的基类的默认实现,但所有其他预定义的方法/属性/等仍然取自基类!

一个简单的例子是:

// base digit class
public class Digit
{
    public int N { get; set; }
    // default output
    public virtual string Print()
    {
        return string.Format("I am base digit: {0}", this.N);
    }
}

public class One : Digit
{
    public One()
    {
        this.N = 1;
    }
    // i want my own output
    public override string Print()
    {
        return string.Format("{0}", this.N);
    }
}

public class Two : Digit
{
    public Two()
    {
        this.N = 2;
    }
    // i will use the default output!
}

当创建两个对象并调用Print时:

var one = new One();
var two = new Two();
System.Console.WriteLine(one.Print());
System.Console.WriteLine(two.Print());

输出是:

1
I am base digit: 2

EF 中的延迟评估不是来自virtual关键字 direct,而是来自关键字启用的覆盖可能性(再次来自MSDN on Lazy Loading):

When using POCO entity types, lazy loading is achieved by creating 
instances of derived proxy types and then overriding virtual 
properties to add the loading hook.

当预定义的方法被覆盖时,程序员可以启用延迟加载!

于 2013-07-10T16:13:05.827 回答