3

我有一个简单的数据库方案:用户,帐户。用户与帐户具有一对多的关系。

我已经生成了一个 ado.net 实体数据模型,我可以创建用户和帐户,甚至将它们链接在一起。在数据库中 account.user_id 已正确填写,因此理论上我应该能够通过实体访问 C# 中的 User.Account.ToList() 。

但是,当我尝试访问 User.Account.ToList() 时,结果为零。

User user = db.User.First(U => U.id == 1);
List<Account> accounts = user.Account.ToList(); ##count = 0...

当我在前一个代码之前添加以下代码时,它突然给了我正确的计数 2。

 Account account1 = db.Account.First(A => A.id == 1);
 Account account2 = db.Account.First(A => A.id == 2);
 User user = db.User.First(U => U.id == 1);
 List<Account> accounts = user.Account.ToList(); ##count = 2...??

我在这里想念什么?

4

3 回答 3

2

您应该为此使用ObjectQuery.Include方法。您的方法也有效,但会导致额外的查询。

在你的例子中,你会得到

User user = db.User.Include("Account").First(u => u.id == 1);

您必须弄清楚字符串"Account"是否正确。通常它应该以类似的东西作为前缀MyEntities。这取决于您的实体的名称空间,但通过一些试验和错误,您应该能够弄清楚这一点。

于 2009-04-14T12:08:32.843 回答
2

是的,这是开始使用 Entity 框架时的常见问题 - 父子关系都不是延迟加载的,因此您必须显式加载它们。如果您要在类/方法之间共享对象上下文,您可能需要检查关系是否已经加载:

例如

    if(!user.Account.IsLoaded)
        user.Account.Load();

您可以使用简单的扩展方法使这更容易:

public static class EntityExtensions
{
    public static void EnsureLoaded(this RelatedEnd relatedEnd)
    {
        if (!relatedEnd.IsLoaded)
            relatedEnd.Load();
    }
}

使用它可以使您的负载调用再次更短:

user.Account.EnsureLoaded();

并且由于它使用了一个 RelatedEnd,这对于实体框架中的父子关系来说是常见的,因此您也可以将它用于父引用关系 - 例如

account.UserReference.EnsureLoaded();

正如 rwwilden 所说,如果在这种情况下您总是要使用父对象加载子对象,您可能希望使用 Include 来提高调用效率并避免额外的数据库往返。

于 2009-04-14T12:14:41.703 回答
1

我想我对框架的了解有点少。:)

您需要先显式加载相关帐户。

user.Account.Load();

现在它确实显示正确。

于 2009-04-14T11:53:02.850 回答