简体   繁体   中英

Fail to convert LINQ query result to ToList

  /// <summary>
        /// Get All Countries 
        /// </summary>
        /// <returns></returns>
        public IEnumerable<CountryVM> GetAllCountry( )
        {
            using (Context context  = new Context() )
            {
                var countries = context.COUNTRY.Select(c => new CountryVM()
                     {
                         ID = c.ID,
                         DESCRIPTION = c.DESCRIPTION,
                     }

                ).ToList(); // Gets Exception here.
                return countries;
            }

Why am I not able to convert to ToList() ?

Iget following Exception :

LINQ to Entities does not recognize the method 'System.Collections.Generic.List 1[LANGUAGE] ToList[LANGUAGE](System.Collections.Generic.IEnumerable 1[LANGUAGE])' method, and this method cannot be translated into a store expression.

A common error, and since you may encounter it multiple times, please let me explain why is this happening.

Let's read the error message:

LINQ to Entities does not recognize the method

Linq to entities, the library translating linq expressions to SQL (assuming you're using a SQLServer database), doesn't understand something you're asking it to do. What is it it doesn't get?

'System.Collections.Generic.List1[LANGUAGE] ToList[LANGUAGE] (System.Collections.Generic.IEnumerable1[LANGUAGE])' method

It's quite a long and messy signature because of the namespace and the return type we're not used to see like this, but it is the method you asked Linq2Entities to translate: ToList<LANGUAGE>(IEnumerable<LANGUAGE>) which returns a List<LANGUAGE>. You probably called the extension method .ToList() on a EntityCollection<LANGUAGE> somewhere.

and this method cannot be translated into a store expression.

There, it said it, it can't translate your Linq expression to a store (read: SQL) expression.

Why is Linq2Entities trying to translate your EntityCollection<LANGUAGE>.ToList() to SQL ? Because everything in the lambda expression (the x => do some stuff part) will be translated to SQL. Since nowhere in the shown code is there any mention of a EntityCollection<LANGUAGE>, I'd have to guess it's in the CountryVM 's constructor.

And that's why Zunair Zubair's answers works: your .Select(), and therefore your lambda expression, isn't translated by Linq2Entities, because you're calling it on an object, so there's no SQL involved, thus no translation problem.

SOLUTION

It's hard to advise anything since I don't know what are you trying to achieve in the constructor, but a possible solution would be :

using (Context context = new Context() )
{
    List<LANGUAGE> langs = context.LANGUAGE.ToList();
    return context.COUNTRY.Select(c => new CountryVM(langs)
    {
        ID = c.ID,
        DESCRIPTION = c.DESCRIPTION,
    }).ToList();
}

and remove the hypothetical context.LANGUAGE.ToList(); from this second constructor. This involves two requests to the database and could be optimized further, but not without knowing your intent and table foreign keys.

I suspect that the expression

context.COUNTRY.Select(c => new CountryVM() { ID = c.ID, DESCRIPTION = c.DESCRIPTION, })

is returning a single entity instead of an enumerable, which is why it cannot be converted to a list.

You can try the following

var countries = context.COUNTRY.ToList().Select(c => new CountryVM()
                 {
                     ...
                 }

            ).ToList();
            return countries;

shouldn't this work, assuming your c.ID and c.DESCRIPTION are scalar properties..

var countries = (from c in context.COUNTRY
                 select new CountryVM()
                 {
                     ID = c.ID,
                     DESCRIPTION = c.DESCRIPTION,
                 }).ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM