davin

Just a little thinking and interest!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

    于orm框架而言最显著的一个特征就是延迟加载(lazy laoding),自然entity framework 也不例外,ms的entity frame work 是一个新的强大的数据模型工具,除了orm功能之外,还有其它更多的功能。因此对于了解entity framework是怎样通过不同的方式来体现这一特征,显得十分必要。本文将告诉我们EF在设计时那些所不为人知的:为什么EF不同于那些你所使用过的以及EF是如何实现你所期待的延迟加载这一特征的。认识到ORM并不是一个新的概念,这很重要。有许多优秀的为Ruby ,Python,甚至也有为.net framework (Nhibernate)的ORM框架出现。正是如此,当你关注EF时,你可能陷入一个和我类似的的困惑(延迟加载的方式并不是我想要的)。因为我使用过LINQ to SQL,我非常期待隐式的延迟加载,并且因此EF将会打破这一界限,后来才知道这是错误的。在之前我详细的描述过entity framework 在设计上与Linq to SQL 的不同(或其它的ORM框架像Nhibernate),我想通过code来展示这些,场景非常简单,在数据库里有2张表"Customers" 表和"Orders"表。我用过LINQ to SQL设计器和Entity framework 设计器,这2个设计器都很容易的产生的C# 代码并与我的数据库交互。我的sql 表只有几条数据,Customers只有1条数据,Orders有3条数据是与Customer相关联,

Code

   上面的代码完成的工作正如我期待的。第一个Customer对象从数据库取出,并且我随后就访问那个Customer's 的Orders.LINQ to SQL 会返回到数据库取出Orders。现在下面是我用Entity Framework来做同样的测试,注意有多少行数据在我的datagrid:

Code

   就像上面的例子一样,有时候有些事情犹豫太简单以至我陷入混淆状态,实际上这里暴露出的问题也是为什么EF一出来就遭到一部分人的放弃,这个问题其实并不是Entity framework带来的,而是由于缺乏对EF底层设计的理解。

为什么EF不延迟加载(Lazy Loading)呢?

   正与我以前提到的,Entity Framework 提供 ORM功能(包含延迟加载)。实际上,EF设计小组从来没有对外宣称将会遵从延迟加载的设计风格(Lazy Loading Design Pattern),取而代之的是:EF提供defferredLoading(延期加载)功能。在另一个角度来讲,延迟加载(lazy loading),延迟初始化(lazy initialization),延期加载deffered loading,需要时加载(on-demand loading)和 即使加载(just-in-time loading)所有这些加载方式都意味着同一个意思。 

  在上面的例子中,LINQ to SQL 自动去数据库为第一个Customers加载Orders,可是EF的设计小组并不希望这种自动发生的行为,背后的原因其实很简单:在一个大型的项目中,对于开发人员而言非常清晰地知道何时他们会访问特定的资源(如数据库)是非常重要的。这样的后果就是,需要一个显式的.Load()方法加载对象。否则 你会急切(eagerly)的加载属性在一开始就使用.Inculde调用:

Code

 4 // Or you can
 5 // Explicitly load the orders after retrieving the customer.

 6 var customer = entityFrameworkContext.Customers.First();
 7 
customer.Orders.Load();
 8 this.MyDataGrid2.DataSource = customer.Orders; 

   首先,我非常不喜欢这种设计风格,然而在我和一些天才(Julie Lerman, Elisa Flasko - MSFT and Jonathan Carter - MSFT就这个问题探讨之后,我才知道这个决定之后所展现出的智慧。尽管上面的理由是很好,但他们不能满足所有的设计场景,这里有一个例子在这里你将需要自动延迟加载,并且我将告诉你们在EF中怎样实现这种功能。以这个场景作为一个例子, 我的一个开发小组是关于Sharepoint的项目,结果要求是一个可配置的web应用程序并且用户可以根据自己的需要添加和删除web Parts,我们进行如下假设:

1.开发小组的负责人创建了一个静态类"BusinessObjects",暴露了许多属性,其中之一是"CurrenctCustomer".

2.Web Part "CustomerBasicInfo" 将显示"CurrentCustomer"的名字。

3.Web Part "CustomerAvailableAddresses"将会卡片上的Customer显示一个地址列表。

4.Web Part "CustomerBillingHistory" 将会显示一个Grid的所有Orders.

    在这个场景中"BusinessObjects.CurrentCustomer"的属性不要急切加载".Addresses" and ".Orders" 的Customer对象,如果用户不需要这个Web Part出现在它的画面,但是这就会浪费带宽去下载数据。上面那部分文章,是的一篇文章的一部分,个人觉得写的非常棒,就把它翻译了。虽然我没有使用过Linq to sql。 不过的确看到不少E文里抱怨Linq to sql 的隐式加载带来的麻烦。先看一个简单的例子(还是前几篇关于继承的模型)

  我要通过entitydatasource给gridview配置数据源来访问上面的模型

 

 

 

 

posted on 2008-10-13 23:35  davin  阅读(6533)  评论(15编辑  收藏  举报