#c# #linq
#c# #linq
Вопрос:
Может кто-нибудь объяснить, почему это компилируется, но создает исключение во время выполнения, потому что оно не может правильно перевести в sql / entities? Пытаюсь понять, что происходит за кулисами.
var data = (from e in db.Employees
join egp in db.EmployeeGrievanceMappings on e.EmployeeID equals egp.EmployeeID
join et in db.EmployeeTypes on egp.EmployeeTypeID equals et.EmployeeTypeID
where et.EmployeeTypeName == employeeeType
select new GrievantStewardBO()
{
Id = e.EmployeeADID,
EmployeeID = e.EmployeeID,
EmployeeTypeID = egp.EmployeeTypeID,
GrievanceID = egp.GrievanceID,
EmployeeGrievanceID = egp.EmployeeGrievanceID,
text = string.IsNullOrWhiteSpace( e.EmployeeLastName) ? e.EmployeeFirstName : e.EmployeeLastName "," e.EmployeeFirstName,
FirstName = e.EmployeeFirstName,
LastName = e.EmployeeLastName
}).
ToList();
Я знаю, что могу написать это и заставить его работать правильно, я просто хотел получить некоторое представление о подобных встречах с LINQ.
text = e.EmployeeLastName == null || e.EmployeeLastName.Trim() == "" ? e.EmployeeFirstName : e.EmployeeLastName "," e.EmployeeFirstName
Связанный с этим вопрос: почему Trim() правильно переводит в LINQ?
Комментарии:
1. Linq to objects может обработать это, но выражение не может быть переведено в Sql с помощью Linq-to-sql. Вот полный список неподдерживаемых строковых методов для linq to sql: msdn.microsoft.com/en-us/library/bb882672 (v = против 110).aspx
2. Потому что никто не запрограммировал поставщика сущностей на перевод этого выражения в SQL. Функции не являются бесплатными. Вы можете увидеть, какие строковые функции поддерживаются здесь
3. это linq для sql или entity framework или что-то еще?
4. Это какой -то поставщик Linq. Какой это на самом деле не имеет значения; какой бы поставщик Linq ни использовался, он не поддерживает этот конкретный метод.
5. Если вам не нужна отложенная загрузка, вы можете решить проблему, сначала вызвав
ToList()
ваш результат, который извлечет данные из вашего поставщика Linq и поместит их в Linq to Objects (т. Е. anIEnumerable
).
Ответ №1:
Вы используете «Linq to Entites», вероятно, либо Entity Framework, либо Linq2SQL. При использовании Linq для Entites ваш оператор linq преобразуется в выражение, анализируется, а затем преобразуется в SQL-запрос. Проблема, с которой вы столкнулись, так же проста, как человек, который написал шаг «синтаксического анализа», не поддерживал string.IsNullOrWhiteSpace
синтаксический анализатор, поэтому он не знает, как превратить эту функцию в строку SQL.
Вы должны либо использовать длинную форму, как вы показали, либо обновить до более новой версии вашей библиотеки, которая ее поддерживает. Похоже, что версия Entity Framework 6 на GitHub делает IsNullOrEmpty
это, возможно, вы могли бы создать новый метод IsNullOrWhiteSpace и выполнить запрос, чтобы объединить его.
Ответ №2:
LINQ, который у вас есть, — это выражение, которое преобразуется в SQL. Кто-то должен вычислить выражение и создать результирующий SQL. Этот процесс не знает, что делать IsNullOrWhiteSpace()
, следовательно, он завершится неудачей.
Ответ №3:
Почему? Никто не написал код для обработки этого конкретного метода в используемом вами провайдере LINQ. Вызовы методов не переводятся в SQL (или что бы там ни переводил поставщик) какой-либо процедурой. Вызовы методов обрабатываются в каждом конкретном случае, а общие методы жестко запрограммированы в провайдере. Если никто не написал код для обработки этого метода, метод не работает.
С другой стороны, почему они не обработали этот конкретный метод? Вероятно, они либо повторно использовали код из LINQ в SQL для своего кода генерации, либо хотели работать.NET framework 3.5 и этот метод был добавлен в 4.0