代码之家  ›  专栏  ›  技术社区  ›  netmajor

LINQ to实体中只支持无参数构造函数和初始值设定项

  •  117
  • netmajor  · 技术社区  · 14 年前

    var naleznosci = (from nalTmp in db.Naleznosci
                                  where nalTmp.idDziecko == idDziec
                                  select new Payments
                                  (
                                      nalTmp.Dziecko.Imie,
                                      nalTmp.Dziecko.Nazwisko,
                                      nalTmp.Miesiace.Nazwa,
                                      nalTmp.Kwota,
                                      nalTmp.RodzajeOplat.NazwaRodzajuOplaty,
                                      nalTmp.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
                                      nalTmp.DataRozliczenia,
                                      nalTmp.TerminPlatnosci
                                  )).ToList();
    

    你知道怎么解决这个问题吗?我试着用任何表情组合。。。:/

    12 回复  |  直到 14 年前
        1
  •  128
  •   James Manning    14 年前

    如果没有关于“Payments”的更多信息,这不会有多大帮助,但假设您要创建Payments对象并基于列值设置其某些属性:

    var naleznosci = (from nalTmp in db.Naleznosci
                                  where nalTmp.idDziecko == idDziec
                                  select new Payments
                                  {
                                      Imie = nalTmp.Dziecko.Imie,
                                      Nazwisko = nalTmp.Dziecko.Nazwisko,
                                      Nazwa= nalTmp.Miesiace.Nazwa,
                                      Kwota = nalTmp.Kwota,
                                      NazwaRodzajuOplaty = nalTmp.RodzajeOplat.NazwaRodzajuOplaty,
                                      NazwaTypuOplaty = nalTmp.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
                                      DataRozliczenia = nalTmp.DataRozliczenia,
                                      TerminPlatnosci = nalTmp.TerminPlatnosci,
                                  }).ToList();
    
        2
  •  116
  •   Tony    12 年前

    ToList() ToArray() ,然后使用 Select(…) . 因此,它将使用LINQ来访问集合,并限制不能使用中的参数调用构造函数 就会消失。

    所以你的代码应该是这样的:

    var naleznosci = db.Naleznosci
                              .Where(nalTmp => nalTmp.idDziecko == idDziec)
                              .ToList() // Here comes transfer to LINQ to Collections.
                              .Select(nalImp => new Payments
                                  (
                                      nalTmp.Dziecko.Imie,
                                      nalTmp.Dziecko.Nazwisko,
                                      nalTmp.Miesiace.Nazwa,
                                      nalTmp.Kwota,
                                      nalTmp.RodzajeOplat.NazwaRodzajuOplaty,
                                      nalTmp.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
                                      nalTmp.DataRozliczenia,
                                      nalTmp.TerminPlatnosci
                                  ))
                              .ToList();
    
        3
  •  47
  •   Gene C    13 年前

    我自己刚刚遇到这个错误,我想我应该补充一点,如果 Payment struct ,您也会遇到相同的错误,因为 类型不支持无参数构造函数。

    付款 并使用对象初始值设定项语法将解决此问题。

        4
  •  21
  •   Justin Helgerson    12 年前

    var query = from orderDetail in context.OrderDetails
                join order in context.Orders on order.OrderId equals orderDetail.orderId
                select new { order, orderDetail };
    

    此时,您有一个包含匿名对象的IQueryable。如果要用构造函数填充自定义对象,只需执行以下操作:

    return query.ToList().Select(r => new OrderDetails(r.order, r.orderDetail));
    

    现在您的自定义对象(将两个对象作为参数)可以根据需要填充属性。

        5
  •  10
  •   eugen    8 年前

    首先,我会避免使用

    from ....
    select new Payments
    {
      Imie = nalTmp.Dziecko.Imie,
      ....
    }
    

    这需要一个空构造函数并忽略封装,所以您说new Payments()是一个没有任何数据的有效支付,但是对象必须至少有一个值,可能还有其他必需的字段,具体取决于您的域。

    对于必填字段最好有一个构造函数,但只带来所需的数据:

    from ....
    select new
    {
      Imie = nalTmp.Dziecko.Imie,
      Nazwisko = nalTmp.Dziecko.Nazwisko
      ....
    }
    .ToList() // Here comes transfer to LINQ to Collections.
    .Select(nalImp => new Payments
     (
      nalTmp.Imie,//assume this is a required field
      ...........
      )
      {
         Nazwisko = nalTmp.Nazwisko //optional field
      })
    .ToList();
    
        6
  •  3
  •   m-r Tarakanoff    14 年前

    你可以尝试做同样的事情,但是使用扩展的方法。数据库使用的提供者是什么?

    var naleznosci = db.Naleznosci
                              .Where<TSource>(nalTmp => nalTmp.idDziecko == idDziec)
                              .Select<TSource, TResult>(
                                 delegate(TSource nalTmp) { return new Payments
                                 (
                                     nalTmp.Dziecko.Imie,
                                     nalTmp.Dziecko.Nazwisko,
                                     nalTmp.Miesiace.Nazwa,
                                     nalTmp.Kwota,
                                     nalTmp.RodzajeOplat.NazwaRodzajuOplaty,
                                     nalTmp.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
                                     nalTmp.DataRozliczenia,
                                     nalTmp.TerminPlatnosci
                                 ); })
                              .ToList();
    
        7
  •  1
  •   Muad'Dib    14 年前

    var naleznosci = (from nalTmp in db.Naleznosci
                                  where nalTmp.idDziecko == idDziec
                                  select new Payments()
                                  {
                                      Dziecko.Imie,
                                      Dziecko.Nazwisko,
                                      Miesiace.Nazwa,
                                      Kwota,
                                      RodzajeOplat.NazwaRodzajuOplaty,
                                      RodzajeOplat.TypyOplat.NazwaTypuOplaty,
                                      DataRozliczenia,
                                      TerminPlatnosci
                                  }).ToList();
    

    这将使用无参数构造函数创建新的Payment对象,然后初始化花括号中列出的属性 { }

        8
  •  1
  •   XtraSimplicity    9 年前

    除上述方法外,还可以将其解析为可枚举集合,如下所示:

    (from x in table
    ....
    ).AsEnumerable()
    .Select(x => ...)
    

    这还有一个额外的好处,那就是在构建匿名对象时会更轻松,如下所示:

     (from x in tableName
    select x.obj)
    .Where(x => x.id != null)
    .AsEnumerable()
    .Select(x => new {
       objectOne = new ObjectName(x.property1, x.property2),
       parentObj = x
    })
    .ToList();
    

        9
  •  1
  •   Mahesh    9 年前

    另外,如果要使用具有多个对象的构造函数进行初始化,如果Linq没有返回值,则可能会出现错误。

    所以你可以这样做:

    (from x in table_1
       join y in table_2
       on x.id equals y.id
       select new {
       val1 = x,
       val2 = y
    })
    .DefaultIfEmpty()
    .ToList()
    .Select(a => new Val_Constructor(a.val1 != null ? a.val1 : new Val_1_Constructor(),
                                a.val2 != null ? a.val2 : new Val_2_Constructor()))
    .ToList();
    
        10
  •  1
  •   Yoda    8 年前

    抱歉来晚了,但我发现 this

    根据你的例子,你会写:

    public static IQueryable<Payments> ToPayments(this IQueryable<Naleznosci> source)
    {
      Expression<Func<Naleznosci, Payments>> createPayments = naleznosci => new Payments
      {
        Imie = source.Dziecko.Imie,
        Nazwisko = source.Dziecko.Nazwisko,
        Nazwa= source.Miesiace.Nazwa,
        Kwota = source.Kwota,
        NazwaRodzajuOplaty = source.RodzajeOplat.NazwaRodzajuOplaty,
        NazwaTypuOplaty = source.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
        DataRozliczenia = source.DataRozliczenia,
        TerminPlatnosci = source.TerminPlatnosci,
      };
    
      return source.Select(createPayments);
    }
    

    • 避免在每次出现时使用初始化模式。
    • 使用途径 var foo = createPayments(bar); 以及通过我的IQueryable.ToPayments()可能。
        11
  •  1
  •   wode    8 年前

    我今天也遇到了同样的问题,我的解决方案与Yoda列出的类似,但是它只适用于流利的语法。

    使我的解决方案适应您的代码:

        /// <summary>
        /// use this instead of a parameritized constructor when you need support
        /// for LINQ to entities (fluent syntax only)
        /// </summary>
        /// <returns></returns>
        public static Func<Naleznosci, Payments> Initializer()
        {
            return n => new Payments
            {
                 Imie = n.Dziecko.Imie,
                 Nazwisko = n.Dziecko.Nazwisko,
                 Nazwa = n.Miesiace.Nazwa,
                 Kwota = n.Kwota,
                 NazwaRodzajuOplaty = n.RodzajeOplat.NazwaRodzajuOplaty,
                 NazwaTypuOplaty = n.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
                 DataRozliczenia = n.DataRozliczenia,
                 TerminPlatnosc = n.TerminPlatnosci
            };
        }
    

    然后将基本查询更新为:

    var naleznosci = (from nalTmp in db.Naleznosci
        where nalTmp.idDziecko == idDziec
        select new Payments.Initializer());
    

    这在逻辑上等同于jamesmanning的解决方案,其优点是将成员初始化的膨胀推到类/数据传输对象上

    但是在回顾了我是如何使用它之后,我发现“Initilizer”就足够了(至少对我来说是这样)。

    最后说明:
    在提出这个解决方案之后,我最初的想法是,共享相同的代码并使其适应查询语法也很简单。我不再相信情况会是这样。我认为,如果您希望能够使用这种类型的速记结构,您需要为每个(query,fluent)fluent提供一个方法,如上所述,它可以存在于对象类本身中。

    /// <summary>
    /// use this instead of a parameritized constructor when you need support
    /// for LINQ to entities (query syntax only)
    /// </summary>
    /// <returns></returns>
    public static IQueryable<Payments> Initializer(this IQueryable<Naleznosci> source)
    {
        return source.Select(
            n => new Payments
            {
                Imie = n.Dziecko.Imie,
                Nazwisko = n.Dziecko.Nazwisko,
                Nazwa = n.Miesiace.Nazwa,
                Kwota = n.Kwota,
                NazwaRodzajuOplaty = n.RodzajeOplat.NazwaRodzajuOplaty,
                NazwaTypuOplaty = n.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
                DataRozliczenia = n.DataRozliczenia,
                TerminPlatnosc = n.TerminPlatnosci
        };
    }
    

    以及使用方法

    var naleznosci = (from nalTmp in db.Naleznosci
        where nalTmp.idDziecko == idDziec
        select nalTmp).Initializer().ToList();
    
        12
  •  1
  •   eiran    4 年前

    只是使用 ToList() Select

    myDbSet.Where(x => something that minimizes the number of items).ToList().Select(...)
    

    DbSet 打电话后 ToList() 您正在玩对象,然后可以在查询中使用非默认构造函数。

    不是最有效的方式使用时间明智的,但它是一个小集的选择。

        13
  •  0
  •   arslanahmad656    5 年前

    虽然现在回答还晚,但它仍然可以帮助处于困境中的人。因为linqto实体不支持无参数对象构造。然而,投影方法 I可数 .

    所以在选择之前,只需转换你的 液体 I可数 通过使用此代码:

    var result = myContext.SomeModelClass.AsEnumerable().Select(m => m.ToString());
    

        14
  •  0
  •   Jair Marques    4 年前
    IQueryable<SqlResult> naleznosci = (from nalTmp in db.Naleznosci
                                  where nalTmp.idDziecko == idDziec
                                  select new Payments
                                  {
                                      Imie = nalTmp.Dziecko.Imie,
                                      Nazwisko = nalTmp.Dziecko.Nazwisko,
                                      Nazwa= nalTmp.Miesiace.Nazwa,
                                      Kwota = nalTmp.Kwota,
                                      NazwaRodzajuOplaty =                          nalTmp.RodzajeOplat.NazwaRodzajuOplaty,
                                  NazwaTypuOplaty = nalTmp.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
                                  DataRozliczenia = nalTmp.DataRozliczenia,
                                  TerminPlatnosci = nalTmp.TerminPlatnosci,
                              });
    Repeater1.DataSource  = naleznosci.ToList(); 
    Repeater1.DataBind();
    
    
    public class SqlResult
    {
            public string Imie { get; set; }
            public string Nazwisko { get; set; }
            ...
    }