2016-11-13 73 views
-1

我在LINQ声明有这样的错误,但我不明白什么与它的问题,或者我怎样才能解决这个问题:只有参数构造函数在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; } 
} 

我怎样才能解决这个问题? 在此先感谢

+0

错误是什么? – Cologler

回答

3

我该如何解决这个问题?

首先了解问题所在。

在Entity Framework中,在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 = ... 

通常情况下,我不提倡这种做法,原因解释here。但在这种情况下,它可以,因为最后你会使用所有的数据(Data = x),所以你不会从数据库中获取更多的数据。

更深刻的解决方案是从视图模型中完全删除列表。冗余是不一致的原因。为什么所有模型实例都需要相同的整数列表?您只需在需要显示UI的位置创建列表即可。

相关问题