0

结构是基本的。我有一个“App”父级,它有许多“PositionData”子级。我想在单个查询中检索“App”的一些基本数据以及该 App 的最后一个“PositionData”。

查询

            var data = context.Apps.Where(a => a.Id == appId).
            Select(c => new {
                DeviceInfo=c.Device,
                LastPosition=c.PositionData.OrderByDescending(p=>p.DateCreated).FirstOrDefault() 
            }).SingleOrDefault();

执行以下命令会引发“System.NotImplementedException”

为了确保仅在子查询的情况下引发异常,我将其分为 2 个查询,它工作得非常好。

            var tempObj = context.Apps.Where(a => a.Id == appId).SingleOrDefault();
            var data=new {
                DeviceInfo=tempObj.Device,
                LastPosition=tempObj.PositionData.OrderByDescending(p=>p.DateCreated)).FirstOrDefault() 
            };

我已经搜索了很多天,也访问了 pg Foundry 论坛,但还没有解决方案。

4

2 回答 2

1

首先我不得不说,我真的不是 postgresql 专家。这个问题绝对是 npgsql 提供程序的错误或至少是功能限制。使用 Sql Servier 提供程序,此语句按预期工作,尽管它创建了一个非常丑陋且缓慢的 TSql 语句。

 var data = context.Apps.Where(a => a.Id == appId).
            Select(c => new {
                DeviceInfo=c.Device,
                LastPosition=c.PositionData.OrderByDescending(p=>p.DateCreated).FirstOrDefault() 
            }).SingleOrDefault();

下面的语句显然比你的要大得多,但不管你信不信,Store 语句要小得多且优化得更好。只要确保 PositionData 表中的 AppId 和 DateCreated 组合是唯一的,结果应该相同。

var data = from a in context.Apps
           join pd in context.PositionData.GroupBy(p => p.AppId)
               .Select(p => new { AppId = p.Key, Date = p.Max(x => x.DateCreated) })
               on a.Id equals pd.AppId into pdgrp
           from lpd in pdgrp.DefaultIfEmpty()
           join p in context.PositionData on lpd equals new { AppId = p.AppId, Date = p.DateCreated } into pgrp
           from lp in pgrp.DefaultIfEmpty()
           where a.Id == appId
           select new {
               DeviceInfo = a.Device,
               LastPosition = lp
           };

也许这个语句也可以在 Postresql 上翻译

更新:一些性能指标。

我已经在本地 SQL 2012 上用非常快的 ssd 进行了测试。对于第一个版本,SQL Server 提供程序为第二个版本创建一个 OUTER APPLY 语句,两个 LEFT OUTER JOINS。TestData 是 15 000 个应用程序和 150 000 个 PositionData 条目。

                 join                      outer apply  
                 reads     duration        reads    duration
all rows          1528          519       444434         912
single row          68            0           35           0

在(AppId ASC,DateCreated DESC)上添加所需的唯一索引后

all rows           884          220        49875         180
single row          28            0           15           0
于 2014-06-24T22:27:52.377 回答
0

我已经在 Npgsql Git Hub 存储库中打开了这个问题。而且似乎这个错误确实是由未实现的 Npgsql 功能引起的。

他们现在已经实现了该功能并将其合并到主分支。下载 Npgsql 和 NpgsqlEntityFramework .dll 版本 >= 2.2 将解决该问题。尽管此修复使用 PostgreSQL v9.3 中引入的“Lateral”sql 关键字,因此还需要 Postgresql 版本。

于 2014-07-02T13:23:26.227 回答