Only parameterless constructors and initializers are supported in LINQ to Entities

后端 未结 14 1320
暗喜
暗喜 2020-11-27 15:27

I have this error in this linq expression :

var naleznosci = (from nalTmp in db.Naleznosci
                              where nalTmp.idDziecko == idDziec
           


        
相关标签:
14条回答
  • 2020-11-27 15:53

    Having just encountered this error myself, I thought I would add that if the Payment type is a struct, you would also encounter the same error because struct types do not support parameterless constructors.

    In that event, converting Payment to a class and using the object initializer syntax will resolve the issue.

    0 讨论(0)
  • 2020-11-27 15:55

    If you still want to use your constructor for initialization and not properties (sometimes this behaviour is desired for initialization purposes), enumerate the query by calling ToList() or ToArray(), and then use Select(…). Thus it will use LINQ to Collections and that limitation of not being able to call constructor with parameters in Select(…) will vanish.

    So your code should look something like this:

    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();
    
    0 讨论(0)
  • 2020-11-27 15:56

    In addition to the aforementioned methods, you can also parse it as an Enumerable collection, like so:

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

    This also has the added benefit of making life easier when building an anonymous object, like this:

     (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();
    

    Remembering, however, that parsing a collection as Enumerable pulls it into memory, so it can be resource intensive! Caution should be used here.

    0 讨论(0)
  • 2020-11-27 15:56
    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; }
            ...
    }
    
    0 讨论(0)
  • 2020-11-27 15:57

    without more info on 'Payments' this doesn't help much, but assuming you want to create a Payments object and set some of its properties based on column values:

    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();
    
    0 讨论(0)
  • 2020-11-27 16:04

    I had the same problem today and my solution was similar to what Yoda listed, however it only works with fluent syntax.

    Adapting my solution to your code: I added the following static method to the object class

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

    and then updated the base query to the following:

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

    This is logically equivalent to James Manning's solution with the advantage of pushing the bloat of member initialization to the Class / Data Transfer Object

    Note: Originally I was using more descriptive names that "Initializer" but after reviewing how I was using it, I found that "Initilizer" was sufficient (at least for my purposes).

    Final Note:
    After coming up with this solution I was originally thinking it would be simple to share the same code and adapt this to work for Query syntax as well. I am no longer believe that to be the case. I think that if you want to be able to use this type of shorthand construction you would need a method for each (query,fluent) fluent as described above which can exist in the object class itself.

    For query syntax an extension method (or some method outside of the base class being used) would be required. (since query syntax wants to operate an IQueryable rather than T)

    Here is a sample of what I used to finally get this to work for query syntax. (Yoda already nailed this but I think the usage could be clearer because I didn't get it at first)

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

    and the usage

    var naleznosci = (from nalTmp in db.Naleznosci
        where nalTmp.idDziecko == idDziec
        select nalTmp).Initializer().ToList();
    
    0 讨论(0)
提交回复
热议问题