我在1:n关系中有两个实体:链接,类别。首先,我得到所有类别和链接,并将它们列入清单。接下来,我手动填充每个类别的链接,但category.Links.Add(link)
连接到db并再次获取链接,它会导致结果中出现双重数据。我知道这个动作是因为延迟加载。延迟加载是真的,我不想禁用它。如何在不连接到db的情况下手动填充每个类别的链接?
请不要提供Eager加载或消除懒惰负载。
var categories = categoryRepository.GetCategories().ToList();
var allLinks = linkRepository.GetLinks().ToList();
foreach (var category in categories)
{
var links = allLinks.Where(l => l.CategoryID == category.CategoryID);
foreach (var link in links)
{
category.Links.Add(link);
}
}
答案 0 :(得分:1)
即使您提到您不想关闭延迟加载我坚持要这样做,因为当您第一次访问导航属性时,将始终触发延迟加载。避免这种情况的唯一方法是:
Links
。原因是用于处理EntityCollection
的{{1}}具有属性Links
,该属性为false(除非通过调用IsLoaded
,否则无法修改)。Load
集合中删除virtual
个关键字。这将禁止仅通过动态代理包装Links
,因此不允许延迟加载。它会更有趣,因为加载中唯一需要的代码应该是前两行 - 在第二次查询执行期间,链接将自动填充到类别中。这里的问题是从自动生成的实体中删除虚拟关键字很难(必须硬编码到T4模板)或者您必须使用自己的实体。Category
属性中的EntityCollection
替换为另一个集合,以某种方式欺骗EF。这并不容易,因为您不能只将新集合分配给Links
- 动态代理将抛出Links
。您必须创建实体的第二个部分部分并添加一些代码,这些代码将直接修改保存集合的私有字段(绕过属性)。即使这样的方法也会产生一些不良后果。默认代码使用一些修正等。关闭延迟加载不会破坏您的功能 - 实际上EF通常在内部执行此操作。你只需要这样做:
InvalidOperationException