2010-06-14 108 views
1

我需要在EF版本1中创建实体数据模型,因为我的虚拟主机还没有Framework 4.0。下面只是一个简单的例子来展示这个问题。实体框架中的外键关系v.1

我有3个表,一个用户表,另一个网页表和一个带访问表。前两个表中的每个表都与访问表具有一对多关系(基本上,它可以作为多对多关系,只有访问表具有其主键和额外字段)

使用4.0这个版本可以工作,但它不适用于v.1。 “访问”的计数为0,所以测试字符串返回“”...为什么,我将如何访问第1版中的外键关系?

UsersEntities context = new UsersEntities(); 
var users = context.Users; 
string result = ""; 
foreach (var user in users) 
{ 
    foreach (var visit in user.Visits) 
    { 
     result += visit.Webpage.Url + "\n"; 
    } 
} 

因此,foreach循环遍历用户,它可以正常工作,但内部循环从不输入,因为没有访问返回。再次,在Framework 4.0中,它使用相同的数据库工作正常。

那么,怎么了?

回答

2

只需将您的代码改成这样:

UsersEntities context = new UsersEntities(); 
var users = context.Users.Include("Visits"); 
string result = ""; 
foreach (var user in users) 
{ 
    foreach (var visit in user.Visits) 
    { 
     result += visit.Webpage.Url + "\n"; 
    } 
} 

通知的包括(...)告诉EF急切地加载每个用户的访问。

有了它,它应该工作。

其实如果网页是导航也一样,你可能需要:

Include("Visits.Webpage"); 

希望这个作品

+0

好棒!它工作得很好,谢谢! 只有几个问题:为什么这是必要的?在Linq to Sql中没有必要,而不是在v.4.0中,所以这是一个在4.0中得到纠正的缺点,或者这个“Include”的目的是什么? 此外,当像这样导航数据模型时,需要遍历许多步骤(“点”)以获得所需的对象。我正在考虑最少知识的原则,或者说你应该避免这一点的“德米特法则”。这是一个问题吗?否则我不知道该怎么做......(我问,因为我试图更多地了解设计原理)。 – Anders 2010-06-15 08:07:26

+0

在L2S中,当您访问导航时,它会默默加载 - 也称为lazyloading。 至于德米特法则,我还没有看到一个ORM,允许您折叠导航以避免这种违规行为。 即x.YZ而不是x.Y.Z – 2010-06-16 00:37:08

+0

当您事先知道需要某些数据时,您可以使用Include - lazyloading - 当您拉回大量结果时可能很有用,并且可能只需要一些结果中的相关项目。即预先将所有数据拉回是浪费。 – 2010-06-16 00:38:27