c# - 在编译表达式之前测试空子
问题描述
我正在尝试通过 检索一个值Expression
,但我有一个场景,模型上的子属性为 null 并且我得到一个NullReferenceException
.
该场景发生在我以以下方式使用模型的情况下,x
视图中的模型在哪里并且它不为空,但Contact
属性为空:
x => x.Contact.Email
然后我使用以下方法检索该值:
public static FieldInfo Get<TModel, TProperty>(HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression)
{
object value = null;
if (html.ViewData.Model != null)
{
value = expression.Compile()(html.ViewData.Model);
}
// other code
}
如何调整此代码以测试子属性上的 null 还是不可能的?
解决方案
为了在我的IQueryable
左外连接实现中处理这个问题,我使用了一个ExpressionVisitor
替换null.member
为null
. 您可以在Expression
EF/LINQ to SQL 支持的 .
public static class ExpressionExt {
public static TE AddTestForNull<TE>(this TE orig) where TE : Expression => (TE)(new NullTestVisitor().Visit(orig));
}
/// <summary>
/// ExpressionVisitor to replace a obj.member Expression with a null test ((obj == null) ? null : obj.member)
/// </summary>
public class NullTestVisitor : System.Linq.Expressions.ExpressionVisitor {
public override Expression Visit(Expression node) {
if (node is MemberExpression nme)
return Expression.Condition(Expression.MakeBinary(ExpressionType.Equal, nme.Expression.AddTestForNull(), Expression.Constant(null, nme.Expression.Type)),
Expression.Constant(null, nme.Type),
nme);
else
return base.Visit(node);
}
}
然后,当您需要处理此类问题时Expression
,只需继续AddTestForNull
:
value = expression.AddTestForNull().Compile()(html.ViewData.Model);
这将在每个级别添加测试 - 如果您有x => x.member.testMember
,它将被替换为((x == null ? null : x.member) == null ? null : x.member.testMember)
.
推荐阅读
- c# - 我想使用带有字符串变量的 out 参数
- xml - div 中所有 /p 的 Xpath,但不包括包含特定文本的 /p/i
- node.js - 填充猫鼬返回_ids数组
- javascript - PHP-jquery-ajax 动态依赖选择 - 难度
- javascript - JavaScript 类与 TypeScript 类
- twitter-bootstrap - 覆盖元素 Z-index
- html - 印度卢比的 HTML 实体名称是什么
- node.js - 将 stripeCharge 函数上传到 Firebase 云函数不起作用
- python - 如何使用 Python (FLASK) 实现 Google Drive V3 API
- entity-framework-core - 告诉我如何正确制定 EF 核心的数据库结构