2 回答
TA贡献1850条经验 获得超11个赞
为了在我的IQueryable左外连接实现中处理这个问题,我使用了一个ExpressionVisitor替换null.member为null. 您可以在ExpressionEF/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).
TA贡献1780条经验 获得超4个赞
您是否可以调整 Get(..) 方法以使用 Func 而不是表达式?
表达式不允许 Null Coalescing 或 Null Propagation 运算符。但是函数可以。
//Yours
public static FieldInfo Get<TModel, TProperty>(HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression) { ... }
//Potential solution for you
public static FieldInfo Get<TModel, TProperty>(HtmlHelper<TModel> person, Func<TModel, TProperty> func) { ... }
表达式不允许 Null Coalescing 或 Null Propagation 运算符。但是函数可以。
请原谅类型的差异。我正在使用我当时最容易获得的东西来为你创建一个具体的例子。
请注意,调用的是 Invoke() 方法而不是 Compile()
public static object Get<Person, TProperty>(Person person, Func<Person, TProperty> func)
{
object result = null;
if (person != null)
{
result = func.Invoke(person);
}
return result;
}
示例使用
var personNoContact = new Person { Contact = null };
var result = Get(personNoContact, x => x.Contact?.Email.EmailAddress ?? "");
以下类用于测试
public class Person
{
public Contact Contact { get; set; }
}
public class Contact
{
public Email Email { get; set; }
}
public class Email { public string EmailAddress { get; set; } }
- 2 回答
- 0 关注
- 111 浏览
添加回答
举报