3

Here's yet another "LINQ to entities does not recognize the method question"... however, isn't the code below doing fundamentally the exact same thing?

Works:

var returnData = from x in MyEntities.MyDBSet
                        where x.MyDBSetPrimaryKey == id
                        select new Models.MyModelDTO
                        {
                            MyPropOne = (int)x.MyModel.MyOtherPropOne,
                            MyPropTwo = x.MyOtherPropTwo ?? 0,
                            MyPropThree = x.MyModel.MyOtherPropThree,
                            MyPropFour = x.MyModel.MyOtherPropFour,
                            MyPropFive = x.MyModel.Entity.MyOtherPropFive,
                            MyPropSix = x.MyModel.MyOtherPropSix == null ? 0 : (decimal)x.MyModel.MyOtherPropSix,
                            MyPropSeven = x.MyModel.SomeType.MyOtherPropSeven,
                            MyPropEight = (int)x.MyModel.MyOtherPropEight,
                            MyPropNine = x.MyModel.MyPropNine == null ? 0 : (int)x.MyModel.MyOtherPropNine,
                            MyPropTen = x.MyModel.MyOtherPropTen == null ? 0 : (int)x.MyModel.MyOtherPropTen,
                            MyPropEleven = x.OtherEntity.MyOtherPropEleven,
                            MyPropTwelve = x.MyOtherpropTwelve
                        };

Doesn't Work:

The same exact assignments wrapped in an extension method:

public static MyModelDTO ToModelDTO(this MyModel x)
    {
        return new MyModelDTO()
        {
            MyPropOne = (int) x.MyModel.MyOtherPropOne,
            MyPropTwo = x.MyOtherPropTwo ?? 0,
            MyPropThree = x.MyModel.MyOtherPropThree,
            MyPropFour = x.MyModel.MyOtherPropFour,
            MyPropFive = x.MyModel.Entity.MyOtherPropFive,
            MyPropSix = x.MyModel.MyOtherPropSix == null ? 0 : (decimal) x.MyModel.MyOtherPropSix,
            MyPropSeven = x.MyModel.SomeType.MyOtherPropSeven,
            MyPropEight = (int) x.MyModel.MyOtherPropEight,
            MyPropNine = x.MyModel.MyPropNine == null ? 0 : (int) x.MyModel.MyOtherPropNine,
            MyPropTen = x.MyModel.MyOtherPropTen == null ? 0 : (int) x.MyModel.MyOtherPropTen,
            MyPropEleven = x.OtherEntity.MyOtherPropEleven,
            MyPropTwelve = x.MyOtherpropTwelve
        };
    }

And later called:

var returnData = from x in MyEntities.MyDBSet
                        where x.MyDBSetPrimaryKey == id
                        select x.ToModelDto();

Resulting in:

LINQ to Entities does not recognize the method 'MyExtensionMethods.MyModels.MyModelDTO ToModelDTO(API.Models.MyModel)' method, and this method cannot be translated into a store expression.
steamrolla
  • 2,373
  • 1
  • 29
  • 39

2 Answers2

6

When the query provider sees that method it doesn't know what to do with it. It can't go in and see the source code of the method, the way it can look into Expression objects and see what is done. It can't evaluate it on the client side as it doesn't have the items yet, and it can't think of any SQL to translate that method call into.

Instead you should write a method that takes an IQueryable and returns another IQueryable, like so:

public static IQueryable<MyModelDTO> ToModelDTO(this IQueryable<MyModel> query)
{
    return query.Select(x => new MyModelDTO()
    {
        MyPropOne = (int)x.MyModel.MyOtherPropOne,
        MyPropTwo = x.MyOtherPropTwo ?? 0,
        MyPropThree = x.MyModel.MyOtherPropThree,
        MyPropFour = x.MyModel.MyOtherPropFour,
        MyPropFive = x.MyModel.Entity.MyOtherPropFive,
        MyPropSix = x.MyModel.MyOtherPropSix == null ? 0 : (decimal)x.MyModel.MyOtherPropSix,
        MyPropSeven = x.MyModel.SomeType.MyOtherPropSeven,
        MyPropEight = (int)x.MyModel.MyOtherPropEight,
        MyPropNine = x.MyModel.MyPropNine == null ? 0 : (int)x.MyModel.MyOtherPropNine,
        MyPropTen = x.MyModel.MyOtherPropTen == null ? 0 : (int)x.MyModel.MyOtherPropTen,
        MyPropEleven = x.OtherEntity.MyOtherPropEleven,
        MyPropTwelve = x.MyOtherpropTwelve
    });
}

Here the mapping is still compiled down into an Expression that the query provider can parse. Now you can do:

var returnData = (from x in MyEntities.MyDBSet
                  where x.MyDBSetPrimaryKey == id
                  select x)
                  .ToModelDTO();
Servy
  • 202,030
  • 26
  • 332
  • 449
  • Is it possible to create an Extension method that could be executed inside of your .Select() method, inside of the new MyModelDTO() initializer? I have some properties that I'd like to be able to perform WHERE logic on separately inside of the .Select() method... essentially performing a filtered include on related entities. – Jason Parker Jun 05 '14 at 22:26
  • @ClearCloud8 It really depends on the specifics of what you want to do, so you're really best of creating a new question which can include some examples of what you'd like to be able to write. – Servy Jun 06 '14 at 13:50
-1

Your problem and possible solutions are not really any different than many of the other "LINQ to entities does not recognize the method" questions.

For examples, see https://stackoverflow.com/a/7259649/120955 and https://stackoverflow.com/a/18901609/120955

Community
  • 1
  • 1
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315