LINQ to Entities中仅支持无参数构造函数

时间:2016-11-13 08:16:20

标签: c# linq linq-to-entities

我的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”CLass

 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; }
}

我该如何解决这个问题? 提前致谢

1 个答案:

答案 0 :(得分: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。 EF非常清楚如何做到这一点。但结果是......好笑。如果检查生成的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。