Ado.Net实体:对象不显示链接成员(外键)
我有一个简单的数据库方案:用户,帐户。 用户与帐户有1对多的关系。
我已经生成了一个ado.net实体数据模型,我可以创建用户和帐户,甚至可以将它们链接在一起。 在数据库中正确填充了account.user_id,因此理论上我应该能够通过实体访问C#中的User.Account.ToList()。
但是,当我尝试访问User.Account.ToList()时,我得到零结果。
User user = db.User.First(U => U.id == 1); List 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 accounts = user.Account.ToList(); ##count = 2...??
我在这里想念的是什么?
您应该使用ObjectQuery.Include方法。 您的方法也有效,但会产生额外的查询。
在你的例子中你会得到
User user = db.User.Include("Account").First(u => u.id == 1);
你必须弄清楚字符串"Account"
是否正确。 通常它应该以MyEntities
类的前缀为前缀。 这取决于您的实体的命名空间,但是通过一些试验和错误,您应该能够解决这个问题。
是的,这是开始使用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();
并且因为它使用了一个在entity framework中父子关系通用的RelatedEnd,所以你也可以将它用于父引用关系 – 例如
account.UserReference.EnsureLoaded();
正如rwwilden所说,如果您总是要在这种情况下使用父对象加载子对象,您可能希望使用Include来提高调用效率并避免额外往返数据库。
我想我的知识有点小。 🙂
您需要先显式加载相关帐户。
user.Account.Load();
现在它确实正确显示。