实体框架中的映射?

时间:2013-07-10 15:48:27

标签: c# .net entity-framework

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

public virtual Person person { set; get; }

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

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

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

虚拟关键字在此实例中的作用是什么?如果我们在没有虚拟关键字的情况下尝试此操作会发生什么?

2 个答案:

答案 0 :(得分:3)

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

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

关于关系,无论何时创建一个在数据库中具有例如1:N关系的实体,您都可以拥有一个EF自动列出其关系的集合,因此您可以在代码中使用它,就像这个例子一样,假设“人1:N订单”:

var ordersFromSomePerson = person.Orders;

答案 1 :(得分:0)

为了回答有关为什么虚拟ICollection 在EF中启用延迟加载的问题,我们需要C#中虚拟关键字的定义和含义。来自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.

它是Object Oriented Programming概念的继承机制的一部分。

通常情况下,子类需要另一个(扩展)功能作为基类。在这种情况下,虚拟关键字允许程序员覆盖(如果需要,此当前实现的基类的默认实现,但所有其他预定义方法/属性/等。还是从基类中取出来的!

一个简单的例子是:

// 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中的延迟评估不是来自虚拟关键字direct,而是来自覆盖关键字启用的可能性(再次来自MSDN延迟加载):

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.

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