linq - 无法使用 MVC 核心中的影子属性翻译 LINQ 表达式
问题描述
我已经用与本文中的方法类似的方法实现了影子属性。我有一个损坏的 LINQ 查询,到目前为止它使用常规 CreatedDate 属性运行良好,现在我无法将它与 Shadow 属性一起使用:
public List<Gastos> GetGastosPorSeleccion(ApplicationDbContext context, int idProveedor, int idContenedor, int idPuerto)
{
var gastos = context.Gastos
.Where(
item =>
(
(item.IdProveedor == idProveedor)
&& (item.IdContenedor == idContenedor)
&& (item.IdPuerto == idPuerto)
)
)
.GroupBy(item => item.Tipo)
.Select(item => item.OrderByDescending(item => EF.Property<DateTime>(item, "CreatedDate"))
.FirstOrDefault())
.ToList();
return gastos;
}
这曾经在不使用 CreatedDate 作为 EF.Property 的情况下工作,但是,它不能再被翻译,我也不能进行客户端查询,因为我没有将该属性作为对象的一部分。
该查询应该首先按某些表字段进行过滤,然后按类型分组并从每个分组中检索最新记录。
这是我得到的例外:
System.InvalidOperationException: 'LINQ 表达式'(GroupByShaperExpression: KeySelector: (g.Tipo), ElementSelector:(EntityShaperExpression: EntityType: Gastos ValueBufferExpression: (ProjectionBindingExpression: EmptyProjectionMember) IsNullable: False)) .OrderByDescending(item => EF.Property( item, "CreatedDate"))' 无法翻译。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。有关详细信息,请参阅 https://go.microsoft.com/fwlink/?linkid=2101038。
通过这样重写,查询在 LINQPad6 上运行良好:
Gastos
.Where(
item =>
(
(item.IdProveedor == idProveedor)
&& (item.IdContenedor == idContenedor)
&& (item.IdPuerto == idPuerto)
)
)
.GroupBy(item => item.Tipo)
.Select(item => item.OrderByDescending(item => item.CreatedDate)
.FirstOrDefault())
解决方案
使用函数链编写不可翻译的 LINQ 查询是多么容易。不管你是否使用影子属性,查询是错误的,因为 group by 只能返回聚合结果或用于分组的字段 - 而不是整个记录。这是一个 SQL 限制,在这种情况下不要期望 EF 奇迹。
可以使用 EF 中不可用的窗口函数(任何当前版本)有效地编写此查询
这根本不是答案,但如果您可以使用第三方扩展linq2db.EntityFrameworkCore - 那么这个查询应该可以工作:
var rnQuery = from getgastos in context.Gastos
where item.IdProveedor == idProveedor &&
item.IdContenedor == idContenedor &&
item.IdPuerto == idPuerto,
select new
{
Entity = item,
RN = Sql.Ext.RowNumber().Over()
.PartitionBy(item.Tipo)
.OrderByDesc(EF.Property<DateTime>(item, "CreatedDate")).ToValue()
};
var query = from q in rnQuery
where q.RN == 1
select q.Entity;
// switch to alternative LINQ translator
var query = query.ToLinqToDB();
推荐阅读
- c# - 如何将数组从剑道预检传递给 MVC 列表参数?
- azure-service-fabric - Service Fabric 单节点 SingleNodeClusterUpdateNotAllowed
- neo4j - 从 Neo4j 上的 csv 错误加载 - 输入意外结束
- python - 将从 pd.df['x'].mode()[0] 获得的值连接到字典中的键
- python - Python / TXT:在字符串之后复制文本的代码
- r - 计数观察之间的发生
- python - 无法在 Pycharm 中使用 Django 连接到 MongoDB
- php - 带有命名空间 PHP 的 SOAP Post 请求
- sql - 如何使用两个表进行 SQL 查询
- coordinates - xarray 获取非 NaN 变量值的最高坐标