Страницы

Поиск по вопросам

суббота, 7 декабря 2019 г.

AsEnumerable в Entity Framework

#c_sharp #entity_framework #sql_server


Здравствуйте уважаемые специалисты! Хочу задать вопрос по Entity Framework. Например
у меня есть такой код
return from city in context.City
       where SomeFunc(city, id, name)
       select new City(city);

bool SomeFunc(City city, int id, int name)
{
    return city.Id == id || city.Name == name || city.Code == name;       
}

когда я выполняю код то получаю такое исключение 

LINQ to Entities does not recognize the method  and this method cannot be translated
into a store expression

В интернете советуют использовать метод AsEnumerable
return from city in context.City.AsEnumerable()
       where SomeFunc(city, id, name)
       select new City(city);

Это работает но очень медленно потому что context.City.AsEnumerable() выдает мне
сразу все города из таблицы и потом выполняет к ним функцию SomeFunc
Можно написать так: 
return from city in context.City
       where city.Id == id || city.Name == name || city.Code == name
       select new City(city);

и все будет работать быстро. Но тогда получится такая проблема - это условие может
быть использовано еще в каком-то методе и тогда надо будет дублировать этот код что
не есть хорошо. Как быть? Может быть в Entity Framework есть какой то способ избежать
и дублирования кода и выполнения условий в SQL а не в C#? Заранее спасибо!     


Ответы

Ответ 1



Попробуйте перейти от Func к Expression: Expression> SomeFunc(int id, string name) { return city => city.Id == id || city.Name == name || city.Code == name; } var result = cities.Where(SomeFunc(id, name)).Select(city => new City(city));

Ответ 2



Если условие используется в нескольких местах, вынесите эту фильтрацию в отдельный метод: private IQueryable GetFilteredCities(int id, string name) { return context.City .Where(city => city.Id == id || city.Name == name || city.Code == name); } Затем, его можно использовать в других методах: var cities1 = GetFilteredCities(1, "Moscow"); var cities2 = GetFilteredCities(3, "London").Where( ... ).Select( ... ); В результате выполнения метода GetFilteredCities SQL-запрос выполняться не будет, а будет просто формироваться условие. Непосредественно запрос выполнится при вызове методов AsEnumerable(), ToList() или ToArray().

Комментариев нет:

Отправить комментарий