Член дерева выражений, связывающий null с объединяемым объектом?

#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 Я добавил больше деталей в свой ответ. Надеюсь, это поможет.