LINQ to Entities中只支持无参数构造函数
本文关键字:参数 构造函数 支持 to Entities LINQ | 更新日期: 2023-09-27 18:17:51
我有这个错误在我的LINQ语句,但我不明白是什么问题,或者我怎么能解决它:
这是我的LINQ: int year = 2016;
int month = 11;
DateTime dateFrom = new DateTime(year, month, 1);
DateTime dateTo = dateFrom.AddMonths(1);
int daysInMonth = DateTime.DaysInMonth(year, month);
var data = db_pdv.Pdv.Where(x => x.Fecha >= dateFrom && x.Fecha < dateTo);
var model_pdv = data.GroupBy(x => new { Pdv = x.Clave_PDV, Nombre_Pdv = x.Nombre_Pdv, Turno = x.Turno, Nombre_Turno = x.Nombre_Turno, Pla_ID = x.Platillo, Nombre_Platillo = x.Nombre_Platillo, Precio = x.Precio })
.Select(x => new DishVM()
{
Clave_PDV = x.Key.Pdv,
Nombre_Pdv = x.Key.Nombre_Pdv,
Turno = x.Key.Turno,
Nombre_Turno = x.Key.Nombre_Turno,
Platillo = x.Key.Pla_ID,
Nombre_Platillo = x.Key.Nombre_Platillo,
Precio = x.Key.Precio,
Days = new List<int>(new int[daysInMonth]),
Data = x
}).ToList();
这是我的"DishVM"类
public class DishVM
{
public string Clave_PDV { get; set; }
public string Nombre_Pdv { get; set; }
public string Turno { get; set; }
public string Nombre_Turno { get; set; }
public int Platillo { get; set; }
public string Nombre_Platillo { get; set; }
[DisplayFormat(DataFormatString = "{0:C}")]
public decimal Precio { get; set; }
public List<int> Days { get; set; }
[Display(Name = "Quantity")]
public int TotalQuantity { get; set; }
[DisplayFormat(DataFormatString = "{0:C}")]
[Display(Name = "Total")]
public decimal TotalPrice { get; set; }
public IEnumerable<Pdv> Data { get; set; }
}
我该如何解决这个问题?提前感谢
我该如何解决这个问题?
从了解问题是什么开始。
在实体框架中,任何在DbSet
上操作的表达式,如db_pdv.Pdv
,都被转换成SQL。整个表达式。在你的例子中,这个"整个表达式"是model_pdv
,它的结构是db_pdv.Pdv.Where(...).GroupBy(...).Select()
。表达式中包含new List<int>(new int[daysInMonth])
。您将理解将其转换为SQL是不可能的;数据库引擎如何知道如何构造。net List<T>
对象?
那么如何解决呢?
您可以先构建列表,然后构建表达式:
...
var daysList = new List<int>(new int[daysInMonth]);
var data = db_pdv.Pdv.Where(...
...
Precio = x.Key.Precio,
Days = daysList,
Data = x
现在,您已经将SQL转换任务简化为将原始值(整数)转换为SQL。英孚非常清楚如何做到这一点。但结果是……有趣。如果检查生成的SQL,您会看到EF将整数列表转换为某种SQL表。这看起来像…
CROSS JOIN (SELECT
0 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
UNION ALL
SELECT
0 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable2]
UNION ALL
SELECT
0 AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable3]
UNION ALL
...
…等等。
这里发生的事情,基本上是在c#中构建一个列表,将其转换为SQL结构,让数据库构建一个结果集,将结果集转换为c#中的列表——很复杂。
另一个选项是在内存中运行整个语句:
var data = db_pdv.Pdv.Where(x => x.Fecha >= dateFrom && x.Fecha < dateTo)
.AsEnumerable();
var model_pdv = ...
通常,我不提倡这种方法,原因如下所述。但在这种情况下,这是可以的,因为最终你将使用所有的数据(Data = x
),所以你不会从数据库中获取超过你需要的。
一个更深刻的解决方案是从视图模型中完全删除列表。冗余是不一致之母。为什么所有的模型实例都需要相同的整数列表?您应该只能够在需要它来呈现UI的地方构建一次列表。