今天在使用EF Lazy Loading时遇到了一个错误:Database already exists and can't be created again.

翻出Lazy Loading来查了一下才找出了错误所在。首先看我开始的错误代码,entity是这么定义的:

public class TaskDay
    {
        public int Id { get; set; }
        public DateTime Day { get; set; }
        public IList<TaskDetail> Tasks { get; set; }
    }


错误之处有两点:

1. 关系属性定义称了IList,应该是ICollection。这个还没有查到为什么,可能是EF定义的规范。如果定义成ICollection,则使用Include方法Loading的时候是eager loading。

2. 在于没有将rational entity,Tasks定义为virtual的。因为关于Lazy Loading有这样一段描述,

Lazy loading is the process whereby an entity or collection of entities is automatically loaded from the database the first time that a property referring to the entity/entities is accessed. 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. For example, when using the Blog entity class defined below, the related Posts will be loaded the first time the Posts navigation property is accessed:

大概的意思就是在第一次访问Tasks时实例化TaskDetail并且重写改属性去实现Tasks的加载。猜想这个loading hook的意思就是在Sql查询的expression中加join。

所以,Lazy Loading和Eager Loading的区别就在于virtual这个关键字。加上就是Lazy,去掉就是eager。

更多关于EF中的Loading规范,http://msdn.microsoft.com/en-us/data/jj574232.aspx

============去复习virtual的分割线=====================

1. 定义。

virtual是用来修饰属性,方法,索引器,事件声明等这些类成员的,使他们可以在派生类中被重写。一般用来进行版本控制(不同version进行不同重写,实现不一样的功能)。

既然与派生有关(间接跟类的实例化有关),virtual不能跟abstract,static,private(不能被派生类访问)等一起使用。

2. 规范。

派生类中使用override或new关键字进行虚方法重写。如果没有关键字,编译器默认为new。

override指重写基类虚方法。new指隐藏基类虚方法。

如果有多个方法与调用兼容(例如,存在两种同名的方法,并且其参数与传递的参数兼容),则 C# 编译器将选择最佳方法进行调用。这个规则比较变态,建议写的时候避免。如果必须要用,可以使用base关键字强制调用重写方法,例如, ((Base)d).DoWork(val);  // Calls DoWork(int) on Derived.

posted on 2013-10-10 14:14  小凯Ki  阅读(2276)  评论(0编辑  收藏  举报