简体   繁体   中英

Using extension method in Linq to Entities

Code:

public static IEnumerable<TableRowModel> GetRows()
        {
            var to_ret = db.TableRows.select(x=> new TableRowModel(){
                TableRowId = x.TableRowId,
                Type = x.Type,
                Name = x.Name,
                CreatedAt = x.CreatedAt,
                ModifiedAt = x.ModifiedAt,
                Enums = x.Enums.Select(y => y.ToEnumModel()),
            });
            return to_ret;
        }

public static EnumModel ToEnumModel(this Enum x)
        {
            var to_ret = new EnumModel()
            {
                CFPId = x.CFPId,
                CreatedAt = x.CreatedAt,
                ModifiedAt = x.ModifiedAt,
            };
            return to_ret;
        }

I get the following error when using the GetRows method:

LINQ to Entities does not recognize the method

Given the error, it's understood that LINQ To Entities is not able to recognize the extension method ToEnumModel . I would like to know if there is a way around this? So that I would not be repeating ToEnumModel code again in GetRows extension.

Under normal circumstances, when performing an operation like a Where in EntityFramework, it isn't actually executed in memory like when you operate on an enumerable (like a List). Instead, it converted into SQL which is then executed by the Db provider. This means that doing certain things, such as using extension methods on objects, is not an option, as the converter cannot turn such things into SQL.

The quickest and easiest solution would be to load your set in-memory, where it can be operated on like any other enumerable. You can do this like so:

var result = myDbSet.AsEnumerable().Etc()

Etc() here represents all other operations you want to run. Be advised however, that this will load all data into memory, which may be prohibitively slow and expensive in some scenarios. One way to alleviate this is to put AsEnumerable() right before you need to use the extension method, thus offloading as many operations as possible to the provider. For example this:

var result = myDbSet.Where([condition]).AsEnumerable().Select(item => item.ExtensionMethod());

Might be much quicker and lighter than this:

var result = myDbSet.AsEnumerable().Where([condition]).Select(item => item.ExtensionMethod());

Your ability to use extension methods in EF is limited, but you can still extend your IQueryable s

public static class Extensions
{
    public static IQueryable<MyModelVM> SelectVMs(this IQueryable<MyModel> models)
    {
        return models.Select(x => new MyModelVM { MyModelId = x.MyModelId });
    }
}

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