如果我使用join()方法,包括()方法不再工作,如:LINQ到实体 - 包括不加载
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()方法,包括()方法不再工作,如:LINQ到实体 - 包括不加载
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
没有加载
没有加盟,包括()的作品
李
更新:其实我最近添加了另一个提示,涵盖了这一点,并提供了一个替代可能更好的解决方案。这样做是为了延缓使用include(),直到查询结束,看到这个以获取更多信息:Tip 22 - How to make include really 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
这是实体框架称为关系修正功能的副作用。
在我的EF Tips series中查看此Tip 1了解更多信息。
尝试了更详细的方式来
做或多或少同样的事情
获得相同的结果,但更多的datacalls:
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(); }
}
你还会得到相同的(意外的)结果吗?
编辑:更改了第一句,因为它是不正确的。感谢指针评论!
那么与“Item.Member”相关的“实体”(即导航的另一端)的导航属性的名称是什么。你应该使用这个而不是连接。例如,如果“实体”添加一个名为成员属性与1的基数和会员有一个名为很多的基数项目属性,你可以这样做:
from e in dc.Entities.Include("Properties")
where e.Member.Items.Any(i => i.Collection.ID == collectionID)
select e
我猜在属性你的模型在这里,但这应该给你一个总的想法。 在大多数情况下,在LINQ to Entities中使用联接是错误的,因为它表明您的导航属性设置不正确,或者您没有使用它们。
试试这个:
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")
所以,我知道我迟到了这里的聚会,但我想我会加入我的发现。这应该是对亚历克斯詹姆斯的帖子的评论,但是因为我没有名气,所以不得不去这里。
所以我的答案是:它似乎并不像你打算的那样工作。亚历克斯詹姆斯给出了两个有趣的解决方案,但是如果你尝试它们并检查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();
在此之前的两个例子简单。如果没有包括它产生了非常值得尊敬的SQL:
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])
但随着,OMG:
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
注意2的状态正在回到那里,尽管我们限制。它根本不起作用。 如果我在某个地方出了问题,我会很高兴地发现,因为这是对Linq的嘲弄。我喜欢这个想法,但目前执行似乎并不可用。
出于好奇,我试过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]
更为简洁 - 怪异计数条款,但总体相同的总失败。
有没有人真的在实际的商业应用中使用过这些东西?我真的开始怀疑... 请告诉我我错过了一些明显的东西,因为我真的很想喜欢Linq!
你为什么这么认为?你在执行后有没有值? – pocheptsov 2009-04-27 16:50:17
我猜测“属性”不是你传递给包含的实际字符串。这意味着你已经省略了问题中最重要的部分。另外,我质疑你为什么使用连接;导航属性通常是在Entity Framework中遍历关系的正确方法。 – 2009-04-27 17:36:55
pocheptsov - 我知道属性尚未加载,因为Proeprties.IsLoaded是假的 嗨克雷格 - “属性”是正确的字符串。连接在不同的导航属性项目上。因为我有一个Item对象的属性(Collection.ID)的值,但我想要与它相关的实体。 Lee – 2009-04-27 20:36:18