我有一个多对多关系,其中Content包含指向标记的ContentTags。我在我的实体上放置了相关的[Include]属性来创建属性。
如果我写了枚举ObjectContext.Contents.Include("ContentTags.Tag")
,那么我会按预期包含ContentTags和Tags。当我使用连接时,我的内容实体中缺少ContentTags:
var contentsForTag =
from c in ObjectContext.Contents.Include("ContentTags.Tag")
join ct in ObjectContext.ContentTags on c.Id equals ct.ContentId
join t in ObjectContext.Tags on ct.TagId equals t.Id
where t.Name.ToLower().Contains(lowerTag)
select c;
有什么想法在这里发生了什么?
答案 0 :(得分:2)
我不确定为什么会这样,但我认为这是因为矛盾。 连接说EF应该只加载包含lowerTag的标签,但Include表示应该加载所有标签。我猜EF不能解决这个问题,这就是为什么没有包含它。您应该能够在没有连接的情况下编写查询
var contentsForTag =
from c in ObjectContext.Contents.Include("ContentTags.Tag")
where c.ContentTags.Any(ct => ct.Tag.Name.ToLower().Contains(lowerTag))
select c;
答案 1 :(得分:1)
尝试以下方法:
var anonType =
from c in ObjectContext.Contents
join ct in ObjectContext.ContentTags on c.Id equals ct.ContentId
join t in ObjectContext.Tags on ct.TagId equals t.Id
where t.Name.ToLower().Contains(lowerTag)
select new { Contents = c, ContentTags = ct, Tags = t }).AsEnumerable();
IList<Contents> contentsForTag = anonType.Select(c => c.Contents).ToList();
如果您将所有相关表格放入匿名类型,EF将了解您实际上需要所有这些信息并将其恢复。最好的部分是EF也将负责自动修复,这意味着所有关系都将得到维护。示例的最后一行只是将所需的对象从匿名类型提取到强类型列表中,但是图表的其余部分仍然存活且很好。
答案 2 :(得分:0)
听起来像是“懒惰负载”与“急切负载”差异。 Content类的Tags集合存储在子表中。包括EF在内的许多ORM尝试“延迟加载”集合和其他多对一引用,因为它不知道您是否需要它们,如果不这样做,那将浪费带宽。但是,这意味着您的标记在检索到的实例中不可用。要告诉L2E,是的,您确实需要标记,指定在构建上下文时应该“急切地”遍历子引用。