Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linq到实体-未加载Include()方法_Linq_Entity Framework - Fatal编程技术网

Linq到实体-未加载Include()方法

Linq到实体-未加载Include()方法,linq,entity-framework,Linq,Entity Framework,如果使用联接,Include()方法将不再工作,例如: 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.未加载属性 如果没有连接,Include()可以工作 Lee尝试更详细的方法来做或多或少相同的事情以获得相同的结果,但使用更多的数据调用: var mydat

如果使用联接,Include()方法将不再工作,例如:

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.未加载属性

如果没有连接,Include()可以工作


Lee

尝试更详细的方法来做或多或少相同的事情以获得相同的结果,但使用更多的数据调用:

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的名为Member的属性,而Member有一个基数为many的名为Items的属性,则可以执行以下操作:

from e in dc.Entities.Include("Properties")
where e.Member.Items.Any(i => i.Collection.ID == collectionID) 
select e

我在这里猜测你的模型的属性,但这应该给你一个大概的想法。在大多数情况下,在LINQ to Entities中使用join是错误的,因为这表明您的导航属性设置不正确,或者您没有使用它们。

更新:实际上,我最近添加了另一个技巧,涵盖了这一点,并提供了另一个可能更好的解决方案。我们的想法是将Include()的使用延迟到查询结束,有关更多信息,请参见以下内容:


使用Include()时,实体框架中存在已知的限制。 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
这是实体框架中称为关系修复的特性的副作用

有关详细信息,请参见my中的此项。

尝试以下操作:

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") 
var query=(ObjectQuery)(来自dc.Entities中的e)
将i加入dc。e.ID上的项目等于i.Member.ID
其中(i.Collection.ID==collectionID)
选择(e)
返回查询。包括(“属性”)

因此,我意识到我在这里的聚会迟到了,不过我想我应该补充一下我的发现。这真的应该是对亚历克斯·詹姆斯的帖子的评论,但因为我没有这个名声,所以只能在这里发表

所以我的答案是:它似乎根本不像你想的那样有效。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();
下面是两个示例中较简单的示例。如果没有include,它将生成完全受人尊敬的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])
但是,天哪:

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的状态仍将返回那里。它根本不起作用。 如果我出了什么差错,我会很高兴地发现,因为这是对林克的嘲弄。我喜欢这个主意,但目前执行起来似乎不可行


出于好奇,我尝试了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]
稍微紧凑一点-奇怪的count子句,但总体上相同,完全失败

有人在实际的商业应用程序中使用过这种东西吗?我真的开始怀疑。。。
请告诉我,我错过了一些明显的东西,因为我真的很想喜欢林克

你为什么这么认为?执行后是否为其指定值?我猜“Properties”不是要传递以包含的实际字符串。这意味着你省略了问题最重要的部分。此外,我还质疑您为什么要使用join;导航属性通常是遍历Entity Framework.pocheptsov中关系的正确方法-我知道属性没有加载,因为proeprites.IsLoaded是false,Hi Craig-“properties”是正确的字符串。联接位于不同的导航属性项上。连接之所以存在,是因为我有一个Item对象(Collection.ID)属性的值,但我需要与其相关的实体。这根本不是一回事。您的代码将导致n+1个数据库查询,其中n是检索到的行数。在1个数据库查询中包含结果。我知道我没有做同样的事情-这是一种草率的说法,说我最终会得到相同的结果。这样做的主要原因是查看是否有任何属性以这种方式加载。如果不是,则问题不可能出现在.Include()语法中,而可能出现在数据中(例如,关联的属性记录可能丢失了…)。您好,如果我使用Properties.load()加载属性,那么它确实正确加载了属性。如果我在不包含联接的查询中使用Include(“属性”),例如:从dc.Entities.Include(“属性”)中的e选择e;它工作正常。利兹:情况还是这样吗?如果使用“select new Item{…};”,.Include()语句不起作用?@grimus,当查询生成的元素类型不是实体类型时,将整个查询包装在
Include
中当前似乎不起作用。然而,最初的建议是在
select
子句中获取导航属性值,这似乎仍然可以解决这个问题。