Деревья выражений С# и имеет значение null

Я пытаюсь создать дерево выражений, чтобы создать лямбду, которую можно использовать в предложении EntityFramework Where. Мне нужно проверить значение null, и я пытаюсь использовать is null. Что-то вроде этого:

    var param = Expression.Parameter(typeof(Customer), "data");
    var fieldExpression = Expression.Property(param, "Address");
    var nullTest = Expression.IsNull(fieldExpression);
    var lambda = Expression.Lambda(nullTest, param);
    var compiled = lambda.Compile() as Func<Customer, bool>;

    using dbContext = new TestDbContext();
    var customersWithNullAddress = dbContext.Customers.Where(compiled);

Здесь предполагается, что у dbContext есть DbSet<Customer>, а у Customer есть свойство, называемое Address. Цель состоит в том, чтобы иметь это:

    var customersWithNullAddress = dbContext.Customers.Where(c => c.Address is null);

Но мне нужно динамически генерировать предикат, поскольку он исходит из пользовательского интерфейса, который позволяет пользователю динамически создавать условие фильтра.

Конечно, это не работает, потому что Expression.IsNull не существует. Кажется, я не могу найти какой-либо механизм для этого в деревьях выражений. Я думаю, я могу сделать

    Expression.Equal(fieldExpression, Expression.Constant(null, typeof(Address))

Но это больше не похоже на рекомендуемый способ проверки нуля, и я хочу быть уверен, что он преобразуется в правильный SQL как SELECT * FROM Customer WHERE Address is null

Кто-нибудь может выполнить это сопоставление с образцом в деревьях выражений?

== null уже преобразуется в правильный is null в SQL, поэтому просто используйте Expression.Equal, как вы показали в вопросе.
Evk 21.11.2022 08:00

Кроме того, «Но это больше не похоже на рекомендуемый способ проверки нуля» довольно спорно.

Evk 21.11.2022 08:05
Как настроить Tailwind CSS с React.js и Next.js?
Как настроить Tailwind CSS с React.js и Next.js?
Tailwind CSS - единственный фреймворк, который, как я убедился, масштабируется в больших командах. Он легко настраивается, адаптируется к любому...
LeetCode запись решения 2536. Увеличение подматриц на единицу
LeetCode запись решения 2536. Увеличение подматриц на единицу
Увеличение подматриц на единицу - LeetCode
Переключение светлых/темных тем
Переключение светлых/темных тем
В Microsoft Training - Guided Project - Build a simple website with web pages, CSS files and JavaScript files, мы объясняем, как CSS можно...
Отношения &quot;многие ко многим&quot; в Laravel с методами присоединения и отсоединения
Отношения &quot;многие ко многим&quot; в Laravel с методами присоединения и отсоединения
Отношения "многие ко многим" в Laravel могут быть немного сложными, но с помощью Eloquent ORM и его моделей мы можем сделать это с легкостью. В этой...
В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Карта дорог Беладжар PHP Laravel
Карта дорог Беладжар PHP Laravel
Laravel - это PHP-фреймворк, разработанный для облегчения разработки веб-приложений. Laravel предоставляет различные функции, упрощающие разработку...
0
2
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Операция is null в C# — это синтаксический сахар, который был добавлен задолго до того, как были созданы деревья выражений LINQ. В обычном коде он компилируется в тот же код IL (по крайней мере, в большинстве случаев), что и == null, поэтому на данный момент нет особого смысла добавлять синтаксис в деревья выражений.

Что касается того, как он преобразуется в SQL, == null всегда преобразовывался в IS NULL в SQL со старых добрых дней LinqToSQL. Может быть еще несколько способов заставить некоторые преобразования SQL привести к = NULL — что, конечно, всегда ложно — но вам нужно действительно попытаться вызвать один из них.

Поэтому, если вы просто ищете гарантии того, что литерал something == null всегда будет переводиться в something IS NULL в SQL для EF (или LinqToSQL, или NHibernate, или Linq2DB, или...), вы его получили. Слишком много кода могло бы сильно сломаться, если бы не работало таким образом.

Другие вопросы по теме