У меня есть следующий код:
return this.ObjectContext.BranchCostDetails.Where(
b => b.TarrifId == tariffId && b.Diameter == diameter
|| (b.TarrifId==tariffId && !string.IsNullOrWhiteSpace(b.Diameter))
|| (!b.TarrifId.HasValue) && b.Diameter==diameter);
И я получаю эту ошибку при попытке запустить код:
LINQ to Entities не распознает метод метода Boolean IsNullOrWhiteSpace (System.String), и этот метод нельзя преобразовать в выражение хранилища. "
Как я могу решить эту проблему и написать код лучше, чем этот?
List<string> my = new List<string>(); var i = from m in my where !string.IsNullOrWhiteSpace(m) select m;
В этом случае важно различать
IQueryable<T>
иIEnumerable<T>
. Короче говоряIQueryable<T>
, обрабатывается поставщиком LINQ для доставки оптимизированного запроса. Во время этого преобразования поддерживаются не все операторы C #, так как либо невозможно перевести их в специфичный для внутреннего интерфейса запрос (например, SQL), либо потому, что разработчик не предвидел необходимость в операторе.В отличие от
IEnumerable<T>
выполненного против конкретных объектов и, следовательно, не будет трансформироваться. Таким образом, довольно распространено, что конструкции, которые можно использовать сIEnumerable<T>
, не могут быть использованы,IQueryable<T>
а также те, которыеIQueryables<T>
поддерживаются различными поставщиками LINQ, не поддерживают один и тот же набор функций.Однако есть некоторые обходные пути (например , ответ Фила ), которые изменяют запрос. Кроме того, в качестве более общего подхода можно вернуться к описанию,
IEnumerable<T>
прежде чем продолжить со спецификацией запроса. Это, однако, может привести к снижению производительности - особенно при использовании его в ограничениях (например, в предложениях where). Напротив, при работе с преобразованиями снижение производительности намного меньше, а иногда и вовсе отсутствует - в зависимости от вашего запроса.Таким образом, приведенный выше код также можно переписать так:
ПРИМЕЧАНИЕ. Этот код окажет более сильное влияние на производительность, чем ответ Фила . Тем не менее, это показывает принцип.
источник
Используйте посетитель выражения, чтобы обнаружить ссылки на string.IsNullOrWhiteSpace и разбить их на более простое выражение
(x == null || x.Trim() == string.Empty)
.Ниже приведен расширенный посетитель и метод расширения для его использования. Для этого не требуется никакой специальной конфигурации, просто вызовите WhereEx вместо Where.
Так что, если вы запустите
myqueryable.WhereEx(c=> !c.Name.IsNullOrWhiteSpace())
его, он будет преобразован до!(c.Name == null || x.Trim() == "")
того, как его передадут во что угодно (linq to sql / entity) и преобразует в sql.источник
Вы также можете использовать это для проверки пробелов:
источник
скинет исключение, если
b.Diameter
естьnull
.Если вы все еще хотите использовать свое заявление, лучше используйте эту проверку
источник