#c# #vb.net #linq
#c# #vb.net #linq
Вопрос:
У меня есть запрос LINQ, который текстуально очень похож как на C #, так и VB.net . Я пытаюсь загрузить все заказы из базы данных Northwind с помощью BLToolkit. Это мой класс Order. Обратите внимание, что OrderDate DateTime является обнуляемым DateTime .
[TableName("Orders")]
public class Order : EntityBase<int>
{
public int OrderID;
public DateTime? OrderDate;
}
Код C # linq является:
from ord in Order
where ord.OrderDate == new DateTime(1997, 11, 14)
select ord.OrderID
Код VB linq является:
From order In db.Order _
Where order.OrderDate = #11/14/1997#
Select order.OrderID
При выполнении код C # генерирует это дерево выражений:
.Call System.Linq.Queryable.Select(
.Call System.Linq.Queryable.Where(
.Constant<BLToolkit.Data.Linq.Table`1[Data.Linq.Model.Northwind Order]>(Table(Order)),
'(.Lambda #Lambda1<System.Func`2[Data.Linq.Model.Northwind Order,System.Boolean]>)),
'(.Lambda #Lambda2<System.Func`2[Data.Linq.Model.Northwind Order,System.Int32]>))
.Lambda #Lambda1<System.Func`2[Data.Linq.Model.Northwind Order,System.Boolean]>(Data.Linq.Model.Northwind Order $order) {
$order.OrderDate == (System.Nullable`1[System.DateTime]).New System.DateTime(
1997,
11,
14)
}
.Lambda #Lambda2<System.Func`2[Data.Linq.Model.Northwind Order,System.Int32]>(Data.Linq.Model.Northwind Order $order) {
$order.OrderID
}
и код VB генерирует это дерево выражений:
.Call System.Linq.Queryable.Select(
.Call System.Linq.Queryable.Where(
.Constant<BLToolkit.Data.Linq.Table`1[Data.Linq.Model.Northwind Order]>(Table(Order)),
'(.Lambda #Lambda1<System.Func`2[Data.Linq.Model.Northwind Order,System.Boolean]>)),
'(.Lambda #Lambda2<System.Func`2[Data.Linq.Model.Northwind Order,System.Int32]>))
.Lambda #Lambda1<System.Func`2[Data.Linq.Model.Northwind Order,System.Boolean]>(Data.Linq.Model.Northwind Order $order) {
$order.OrderDate == (System.Nullable`1[System.DateTime]).New System.DateTime(
1997,
11,
14) ?? False
}
.Lambda #Lambda2<System.Func`2[Data.Linq.Model.Northwind Order,System.Int32]>(Data.Linq.Model.Northwind Order $order) {
$order.OrderID
}
Почему VB придерживается ?? False
конца сравнения OrderDate и какое значение это имеет?
Комментарии:
1. Из любопытства, почему? У вас возникли проблемы с одной работой, а не с другой?
2. Да, BLToolkit — это ORM, который преобразует запрос LINQ в запрос SQL. Он не обрабатывает
?? False
то, что вставляет VB.3. Вы пробовали
New DateTime(...)
использовать его в версии VB?4. Да, он генерирует очень похожее дерево выражений, все еще содержащее
?? False
.
Ответ №1:
VB.NET обрабатывает обнуляемые типы немного иначе, чем C #, поэтому VB.NET может быть обратно совместим с VB6.
Значение null в C #, равное Null, является фактическим Null и преобразует его в LINQ в SQL.
VB с нулевым значением, то есть Nothing, имеет значение по умолчанию, определенное внутренне, поскольку VB6 не имеет истинного значения «NULL». Свойство поля с нулевым значением «.Value» ничего не возвращает, если внутренним значением является это значение по умолчанию, в то время как LINQ использует внутреннее значение напрямую.
Тот самый «?? False» — это способ LINQ обрабатывать это свойство «На самом деле не является нулевым», поэтому LINQ to Objects не подходит при использовании типов с нулевым значением. Это не переводится в SQL.
В запросах VB LINQ to SQL, использующих типы с нулевым значением, вы должны связать обычное предложение Where с полем «IsNot Nothing» или «».Проверка «Имеет значение». Это позволяет избежать того, чтобы LINQ неявно создавал проверку «является ли это нулевым».
Пример:
Dim result = From row In Table _
Where row.nullableField.HasValue AndAlso row.nullableField = someValue _
Select row
Или
Dim result = From row In Table _
Where row.nullableField IsNot Nothing AndAlso row.nullableField = anotherValue _
Select row
Комментарии:
1. Потрясающе, именно то, что мне нужно было знать. В LINQ to SQL он не переводится в окончательный SQL, однако я имею дело с ORM, отличным от MS, с открытым исходным кодом, BLToolkit. Похоже, ошибка в том, что они не обрабатывают странную обработку VB с нулевым значением. Очки для вас!