Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.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
C# 有人能解释为什么这两个linq查询返回不同的结果吗?_C#_.net_Sql_Linq_Linq To Entities - Fatal编程技术网

C# 有人能解释为什么这两个linq查询返回不同的结果吗?

C# 有人能解释为什么这两个linq查询返回不同的结果吗?,c#,.net,sql,linq,linq-to-entities,C#,.net,Sql,Linq,Linq To Entities,我有两个linq(到EF4)查询,它们返回不同的结果。第一个查询包含正确的结果,但格式/投影不正确 第二个查询是我想要的,但它缺少一些数据 模式 问题1 请注意属性GameFile。它不是空的。这很好:)注意到linq查询了吗?我急切地加载一个日志条目,然后急切地加载一个游戏文件(对于每个急切加载的日志条目) 这就是我想要的->对于每个渴望加载的LogEntry,请渴望加载GameFile。但是这个预测结果是错误的 好的。。接下来 问题2 注意:上面的图片有一个打字错误。。。请注意,图像

我有两个linq(到EF4)查询,它们返回不同的结果。第一个查询包含正确的结果,但格式/投影不正确

第二个查询是我想要的,但它缺少一些数据

模式

问题1

请注意属性
GameFile
。它不是空的。这很好:)注意到linq查询了吗?我急切地加载一个
日志条目
,然后急切地加载一个
游戏文件
(对于每个急切加载的日志条目)

这就是我想要的->对于每个渴望加载的
LogEntry
,请渴望加载
GameFile
。但是这个预测结果是错误的

好的。。接下来

问题2

注意:上面的图片有一个打字错误。。。请注意,图像键入时,包含关联的键入代码是正确的(即
LogEntry.GameFile

现在更正投影->所有
日志条目
结果。但是请注意,
GameFile
属性现在是空的?我不知道为什么:(我以为我正确地加载了正确的链。所以这是正确的投影,但结果不正确

强制性存储库代码。
public IQueryable GetConnectedClient(
字符串[]包括关联)
{
返回Context.ConnectedClients
.包括关联(包括关联)
.AsQueryable();
}
公共静态类扩展
{
公共静态IQueryable包含关联(
此IQueryable源,字符串包括关联)
{
如果(!string.IsNullOrEmpty(includeAssociation))
{
var objectQuery=源作为objectQuery;
if(objectQuery!=null)
{
返回objectQuery.Include(includeAssociation);
}
}
返回源;
}
公共静态IQueryable包含关联(
此IQueryable源,参数字符串[]包括关联)
{
如果(包括关联!=null)
{
foreach(includeAssociations中的字符串关联)
{
来源=来源。包括关联(关联);
}
}
返回源;
}
}
更新
  • 1:修复了代码示例中注意到的一些打字错误
  • 2:添加了存储库代码,以帮助任何感到困惑的人

看来您还需要一个存储库方法来为您实现这一点;
\u connectedclients respository.getlogentriesfconnectedclients()
我怀疑Craig Stuntz的建议可能管用,但如果不行,以下建议肯定管用:

 var xxxx =_connectedClientRepository
        .GetConnectedClients(new[] { "LogEntry", "LogEntry.GameFile" })
        .AsExpandable()
        .Where(predicate)
        .ToList() // execute query
        .Select(cp => cp.LogEntry); // use linq-to-objects to project the result
Include()
处理查询结果,而不是中间查询。您可以在本文中阅读更多关于
Include()
的内容。因此,一种解决方案是将
Include()
应用于整个查询,如下所示:

var q = ((from cp in _connectedClientRepository.GetConnectedClients()
                                               .AsExpandable()
                                               .Where(predicate) 
          select cp.LogEntry) 
         as ObjectQuery).Include("GameFile").ToList();
那可能行得通,但很难看。我们能做得更好吗

我可以想出两种方法来解决这个问题。这主要取决于您是否确实需要返回实体类型。如果不查看代码的其余部分,我就不能说是否需要返回实体类型。通常,您需要在更新(或修改)时返回实体类型它们。如果您选择用于显示或计算目的,则返回POCO而不是实体类型通常是一种更好的策略。您可以使用执行此操作,当然它在EF 1中也适用。在这种情况下,您可以将存储库方法更改为返回POCO类型:

 public IQueryable<ClientInfo> GetConnectedClients()
 {
      return from cp in _context.Clients
             where // ...
             select new ClientInfo
             {
                 Id = cp.Id,
                 ClientName = cp.ClientName,
                 LogEntry = new LogEntryInfo
                            {
                                LogEntryId = cp.LogEntry.LogEntryId,
                                GameFile = new GameFileInfo
                                           {
                                               GameFileId = cp.LogEntry.GameFile.GameFileId,
                                               // etc.
                                           },
                                // etc.
                            },
                  // etc.
             };
 }
public IQueryable GetConnectedClients()
{
在_context.Clients中从cp返回
where/。。。
选择new ClientInfo
{
Id=cp.Id,
ClientName=cp.ClientName,
LogEntry=newlogentryinfo
{
LogEntryId=cp.LogEntry.LogEntryId,
GameFile=新的GameFileInfo
{
GameFileId=cp.LogEntry.GameFile.GameFileId,
//等等。
},
//等等。
},
//等等。
};
}
请注意,当您使用projection时,没有即时加载、延迟加载和显式加载。只有您的意图,以查询的形式表达。即使您在存储库之外进一步编写查询,LINQ提供程序也会找出您需要的内容


另一方面,您可能需要返回实体类型而不是POCO,因为您打算更新它们。在这种情况下,我会为日志条目编写一个单独的存储库方法,正如Tomas所建议的那样。但我只会在打算更新它们时才这样做,我可能会将其作为更新方法编写,而不是“Get”方法。

您不需要从发送给GetConnectedClient的参数中删除“LogEntry”吗?我的猜测是:投影改变了结果的形状,因此
包含的
不再匹配。这有效吗?
((从_ConnectedClientRespository.GetConnectedClient()中的cp。AsExpandable()。其中(谓词)选择cp.LogEntry)作为ObjectQuery)。包括(“游戏文件”).ToList()
?@Lasse V.Karlsen:我试过了,但没用。我也试过LogEntry.GameFile和LogEntry,LogEntry.GameFile。但也没用。@Craig Stuntz:有趣的一点……我怀疑是这样的。我很快会尝试。但是你有没有链接到其他人详细解释这个问题呢?你也注意到了吗?没别的了比通常的
Include
文档更重要的是,它适用于
ObjectQuery
,而
T
是很重要的。这可能会有帮助:嗯。我想我需要尊重你的意见。我的存储库方法返回IQueriable,linq查询的其余部分执行筛选,而不是hardco
 var xxxx =_connectedClientRepository
        .GetConnectedClients(new[] { "LogEntry", "LogEntry.GameFile" })
        .AsExpandable()
        .Where(predicate)
        .ToList() // execute query
        .Select(cp => cp.LogEntry); // use linq-to-objects to project the result
var q = ((from cp in _connectedClientRepository.GetConnectedClients()
                                               .AsExpandable()
                                               .Where(predicate) 
          select cp.LogEntry) 
         as ObjectQuery).Include("GameFile").ToList();
 public IQueryable<ClientInfo> GetConnectedClients()
 {
      return from cp in _context.Clients
             where // ...
             select new ClientInfo
             {
                 Id = cp.Id,
                 ClientName = cp.ClientName,
                 LogEntry = new LogEntryInfo
                            {
                                LogEntryId = cp.LogEntry.LogEntryId,
                                GameFile = new GameFileInfo
                                           {
                                               GameFileId = cp.LogEntry.GameFile.GameFileId,
                                               // etc.
                                           },
                                // etc.
                            },
                  // etc.
             };
 }