from e in dc.Entities.Include("Properties")
join i in dc.Items on e.ID equals i.Member.ID
where (i.Collection.ID == collectionID)
select e
e.Properties
没有加载
如果没有使用join,Include()可以正常工作
Lee
from e in dc.Entities.Include("Properties")
join i in dc.Items on e.ID equals i.Member.ID
where (i.Collection.ID == collectionID)
select e
e.Properties
没有加载
如果没有使用join,Include()可以正常工作
Lee
更新:实际上,我最近添加了另一个技巧,涉及到这个问题,并提供了一种可能更好的备选解决方案。其思路是将Include()的使用延迟到查询结束时,有关详细信息,请参见:Tip 22 - 如何使include真正包含
在使用Include()时,Entity Framework已知存在限制。某些操作不支持Include。
看起来你可能遇到了其中之一的限制,为了解决这个问题,你应该尝试类似于以下的方法:
var results =
from e in dc.Entities //Notice no include
join i in dc.Items on e.ID equals i.Member.ID
where (i.Collection.ID == collectionID)
select new {Entity = e, Properties = e.Properties};
这将返回属性,如果实体与属性之间的关系是一对多(但不是多对多),则您会发现每个结果的匿名类型在以下位置具有相同的值:
anonType.Entity.Properties
anonType.Properties
尝试这样做:
var query = (ObjectQuery<Entities>)(from e in dc.Entities
join i in dc.Items on e.ID equals i.Member.ID
where (i.Collection.ID == collectionID)
select e)
return query.Include("Properties")
那么"实体"上与"项目.成员"相关联的导航属性的名称是什么呢(即导航的另一端)。您应该使用这个属性来替代join操作。例如,如果在"实体"中添加一个名为"成员"的属性,其基数为1,并且"成员"具有一个名为"项目"的属性,其基数为多个,您可以这样做:
from e in dc.Entities.Include("Properties")
where e.Member.Items.Any(i => i.Collection.ID == collectionID)
select e
我猜测这里涉及到的是您的模型属性,但这应该能给您一个大致的想法。在大多数情况下,在LINQ to Entities中使用join是错误的,因为这表明您的导航属性可能没有正确设置,或者您没有使用它们。
所以,我意识到我来晚了,但我想添加我的发现。这应该是对Alex James帖子的评论,但由于我没有声望,所以只能在这里发布。
我的答案是:它似乎根本不能按照你的意图工作。Alex James提供了两个有趣的解决方案,但如果你尝试并检查SQL,那就太糟糕了。
我正在处理的示例是:
var theRelease = from release in context.Releases
where release.Name == "Hello World"
select release;
var allProductionVersions = from prodVer in context.ProductionVersions
where prodVer.Status == 1
select prodVer;
var combined = (from release in theRelease
join p in allProductionVersions on release.Id equals p.ReleaseID
select release).Include(release => release.ProductionVersions);
var allProductionsForChosenRelease = combined.ToList();
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name]
FROM [dbo].[Releases] AS [Extent1]
INNER JOIN [dbo].[ProductionVersions] AS [Extent2] ON [Extent1].[Id] = [Extent2].[ReleaseID]
WHERE ('Hello World' = [Extent1].[Name]) AND (1 = [Extent2].[Status])
SELECT
[Project1].[Id1] AS [Id],
[Project1].[Id] AS [Id1],
[Project1].[Name] AS [Name],
[Project1].[C1] AS [C1],
[Project1].[Id2] AS [Id2],
[Project1].[Status] AS [Status],
[Project1].[ReleaseID] AS [ReleaseID]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
[Extent2].[Id] AS [Id1],
[Extent3].[Id] AS [Id2],
[Extent3].[Status] AS [Status],
[Extent3].[ReleaseID] AS [ReleaseID],
CASE WHEN ([Extent3].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
FROM [dbo].[Releases] AS [Extent1]
INNER JOIN [dbo].[ProductionVersions] AS [Extent2] ON [Extent1].[Id] = [Extent2].[ReleaseID]
LEFT OUTER JOIN [dbo].[ProductionVersions] AS [Extent3] ON [Extent1].[Id] = [Extent3].[ReleaseID]
WHERE ('Hello World' = [Extent1].[Name]) AND (1 = [Extent2].[Status])
) AS [Project1]
ORDER BY [Project1].[Id1] ASC, [Project1].[Id] ASC, [Project1].[C1] ASC
完全是垃圾。需要注意的关键点是,它返回未被status=1限制的表的外部连接版本。
这会导致错误的数据被返回:
Id Id1 Name C1 Id2 Status ReleaseID
2 1 Hello World 1 1 2 1
2 1 Hello World 1 2 1 1
出于好奇,我尝试使用LinqToSQL dbml而不是LinqToEntities edmx来生成上述混乱的内容:
SELECT [t0].[Id], [t0].[Name], [t2].[Id] AS [Id2], [t2].[Status], [t2].[ReleaseID], (
SELECT COUNT(*)
FROM [dbo].[ProductionVersions] AS [t3]
WHERE [t3].[ReleaseID] = [t0].[Id]
) AS [value]
FROM [dbo].[Releases] AS [t0]
INNER JOIN [dbo].[ProductionVersions] AS [t1] ON [t0].[Id] = [t1].[ReleaseID]
LEFT OUTER JOIN [dbo].[ProductionVersions] AS [t2] ON [t2].[ReleaseID] = [t0].[Id]
WHERE ([t0].[Name] = @p0) AND ([t1].[Status] = @p1)
ORDER BY [t0].[Id], [t1].[Id], [t2].[Id]
尝试使用更冗长的方式 做更多或更少相同的事情 来获得相同的结果,但需要进行更多的数据调用:
var mydata = from e in dc.Entities
join i in dc.Items
on e.ID equals i.Member.ID
where (i.Collection.ID == collectionID)
select e;
foreach (Entity ent in mydata) {
if(!ent.Properties.IsLoaded) { ent.Properties.Load(); }
}