#c# #.net #entity-framework #linq #expression
#c# #.net #entity-framework #linq #выражение
Вопрос:
Я пытаюсь создать привязку дерева выражений, которая создаст объект, если свойство доступно, и установит значение null, если это не так. Например, я хочу получить:
personModel = car.Person == null ? null : new PersonModel()
Но независимо от того, что я пытаюсь, это не удается.
Я попытался объединить
Expression.Coalesce(
Expression.Property(param, "Person"),
Expression.MemberInit(Expression.New(typeof(PersonModel)), MemberAssignment[])
)
Это выдает System.ArgumentException: 'Argument types do not match'
ошибку. Я предполагаю, что дерево выражений ожидает размещения одних и тех же типов в coalesce — поскольку у меня есть несколько nullable перечислений, которые работают в приведенном выше сценарии.
Я попробовал условное
Expression.Condition(
Expression.Equal(Expression.Property(param, "Person"), Expression.Constant(null)),
Expression.MemberInit(Expression.New(typeof(PersonModel)), MemberAssignment[]),
Expression.Constant(null)
)
Это также возникает System.ArgumentException: 'Argument types do not match'
из-за наличия истинного блока Expresison.MemberInit
и наличия ложного блока Expression.Constant
.
Есть ли способ заставить что-то подобное работать?
Ответ №1:
Ваше утверждение personModel = car.Person == null ? null : new PersonModel()
можно перевести как:
Expression.Condition(
Expression.Equal(Expression.Property(Expression.Constant(car), "Person"), Expression.Constant(null,typeof(PersonModel))),
Expression.Constant(null, typeof(PersonModel)), Expression.MemberInit(Expression.New(typeof(PersonModel))));
Похоже, что вы пропустили упомянуть, это typeof для null
константы as Expression.Constant(null,typeof(PersonModel))
.
Объяснение:
Если вы проверяете определение, в .Condition
нем говорится, что оно выдает System.ArgumentException
, когда
тест.Тип не является системным.Логическое значение.-или-если верно.Тип не равен ifFalse.Type
Итак, в вашем случае проверяется, что тип значений в обоих false
true
выражениях и равен PersonModel
. Компилятор может сделать то же самое для false
(new PersonModel()), но не для true
(null), поэтому нам нужно явно указать это.
Комментарии:
1. Ах! Спасибо @gkulshrestha! Любая информация о том, почему нам нужно указать тип null?
2. @GrizzlyEnglish Я добавил больше деталей в свой ответ. Надеюсь, это поможет.