在观看一些实体框架教程时,我发现有很多方法可以在两个实体之间创建关系。但我很难理解这些界限的确切含义。
public virtual Person person { set; get; }
public virtual IEnumerable<Person> person { set; get; }
public virtual ICollection<Person> person { set; get; }
在其中一个视频中,他们解释说当你同时创建一个虚拟和ICollection
的属性时,这会启用延迟加载
虚拟关键字在此实例中的作用是什么?如果我们在没有虚拟关键字的情况下尝试此操作会发生什么?
答案 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.
当预定义方法被覆盖时,程序员可以启用延迟加载!