如何在动态选择中创建带有表达式的“内联if语句”,以进行空值检查?
我写了一个动态选择LINQ表达式,用于一个对象的嵌套属性,但是当它为空时抛出异常。所以我想检查该属性是否为空,就这么简单!
我的意思是:
X.Where(...)
.Select(X => new Y{
...
Z = X.Titles == null ? "" : [Linq]
...
}).FirstOrDefault();
这是我写的
private static Expression GetLocalizedString(Expression stringExpression, SupportedCulture supportedCulture)
{
var expression = Expression.Parameter(typeof(APILocalizedString), nameof(APILocalizedString));
var prop = Expression.Property(expression, nameof(APILocalizedString.SupportedCulture));
var value = Expression.Constant(supportedCulture);
var condition = Expression.Equal(prop, value);
var where = Expression.Call(
typeof (Enumerable),
nameof(Enumerable.Where),
new Type[] { typeof(APILocalizedString) },
stringExpression,
Expression.Lambda<Func<APILocalizedString, bool>>(condition, expression));
var select = Expression.Call(
typeof(Enumerable),
nameof(Enumerable.Select),
new Type[] { typeof(APILocalizedString), typeof(string) },
where,
Expression.Lambda<Func<APILocalizedString, string>>(
Expression.Property(expression, nameof(APILocalizedString.Text)),
expression
));
var first = Expression.Call(
typeof(Enumerable),
nameof(Enumerable.First),
new Type[] { typeof(APILocalizedString) },
stringExpression);
var defaultIfEmpty = Expression.Call(
typeof(Enumerable),
nameof(Enumerable.DefaultIfEmpty),
new Type[] { typeof(string) },
select,
first);
var firstOrDefault =
Expression.Call(
typeof(Enumerable),
nameof(Enumerable.FirstOrDefault),
new Type[] { typeof(string) },
defaultIfEmpty);
var nullCheck = Expression.Equal(stringExpression, Expression.Constant(null, stringExpression.Type));
var result = Expression.IfThenElse(nullCheck, Expression.Constant(""), firstOrDefault);
return result;
}
下面是GetLocalizedString生成的内容:{IIF((X.Titles == null), "", X.Titles.Where(APILocalizedString => (APILocalizedString.SupportedCulture == EN)).DefaultIfEmpty(X.Titles.First()).Select(APILocalizedString => APILocalizedString.Text).FirstOrDefault())}
选择表达式... bindings.Add(Expression.Bind(property, GetLocalizedString(Expression.Property(parameter, "Titles"), SupportedCulture.EN))); ...
下面是错误消息:System.ArgumentException: 'Argument types do not match'
Select属性的类型为String
有没有办法创建一个类似X.Titles == null ? "" : [Linq]
表达式?
1条答案
按热度按时间anauzrmj1#
C#条件
?:
运算子的运算式对等用法是Expression.Condition
。而您使用的Expression.IfThenElse
则是C#if then else
区块的对等用法。这两个方法都会传回
ConditionalExpression
,并填入Test
、IfTrue
和IfFalse
属性。差异在于Condition
的结果Type
是算子的类型,而IfThenElse
的结果是void
,因此无法用于查询表示式树形结构。所以你这个具体问题的答案是:
P.S.作为一个边节点,我从代码片段中得到了几个错误,所以我不得不像这样重新排列它,以便在上面的行中得到w/o错误: