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 關注
- 132 瀏覽
添加回答
舉報