2016-11-13 70 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的位置創建列表即可。

相關問題