2

Good day,

My code generates a run-time error and I'm not sure how to fix this. Any help would be appreciated.

Our code is calling the second Convert method below by passing a list of "offers". The offer is an object from an EDMX model. The first Convert method takes the object and converts it to a DTO class which it then returns back.

When running the program, I experience the following error:

LINQ to Entities does not recognize the method '...Domain.Holdings.OfferDto Convert(...Repository.Offer, System.Nullable`1[System.Int32])' method, and this method cannot be translated into a store expression.

The code looks as follows:

public class OfferDtoMapping
{
    public static OfferDto Convert(Offer offer, int? participantId)
    {
        if (offer == null)
            throw new ArgumentException("The Offer object supplied for conversion cannot be null");

        var unitCost = offer.UnitCost;
        if (offer.Trust.Company.AllowInterDiv && participantId.HasValue)
        {
            Assign another value to unitCost...
        }

        var output = new OfferDto
        {               
            Assign the offer properties to the OfferDto properties...
        };
        return output;        
    }

    public static IList<OfferDto> Convert(IQueryable<Offer> offerList)
    {
        return offerList == null ? new List<OfferDto>() : offerList.Select(ol => Convert(ol, null)).ToList();
    }
}

The error occurs on this line:

 return offerList == null ? new List<OfferDto>() : offerList.Select(ol => Convert(ol, null)).ToList();

I suspect the error has to do with the fact that I am projecting the offerList over a method taking in 2 input parameters. We tried passing 0 instead of NULL (because we initially thought that was the problem) but still got a similar error message.

In order to maintain consistency throughout our solution we want to keep using the Select method instead of replacing this with a foreach statement.

Is there a way of using the Select method in our current situation?

Thank you in advance.

Matei
  • 327
  • 5
  • 17

3 Answers3

2

Linq To Entities tries to convert your Select statement into a valid expression for your underlying database. Since that cannot possibly know about your Convert method, this translation fails, resulting in the error you see.

You can resolve that, by letting Linq to Objects handle the Select statement.

offerList.ToList().Select(ol => Convert(ol, null));
Jens
  • 25,229
  • 9
  • 75
  • 117
2

You can't call methods from linq2entities you can do this in linq2object, so first fetch your data and then call method:

   return offerList == null ? new List<OfferDto>() : offerList.ToList()
                                                    .Select(ol => Convert(ol, null))
                                                    .ToList()

offerList.ToList() fetchs data from DB into memory, and then you can simply run linq2object methods on it. In fact some few predefined system methods are allowed to call from linq2entity, and user defined methods are not allowed (because linq2sql can't make expression tree ).

Saeed Amiri
  • 22,252
  • 5
  • 45
  • 83
2

The error occurs because there is no transaltion for the Convert method in Linq to entities. You need to force evaluation of the data first by calling ToList() on the Iqueryable data. The convert can then be executed outside of Linq to Entites in memory.

return offerList == null ? new List<OfferDto>() : offerList.ToList().Select(ol => Convert(ol, null)).ToList();
AaronHS
  • 1,334
  • 12
  • 29
  • Excellent, thank you and thank you all for such quick answers. I tested it and it works. – Matei Mar 06 '12 at 12:07
  • As an alternative to `ToList()`, you could use `AsEnumerable()`, which might be more efficient, because it doesn't need to allocate the list twice. – svick Mar 06 '12 at 12:34