[英]C# Aggregate for property Expression returns AmbiguousMatchException
我有以下(簡化)課程:
public abstract class BaseSite
{
public int SiteId { get; set; }
public string Name { get; set; }
}
public class OptionalSite : BaseSite
{
public new int? SiteId { get; set; }
}
以下方法:
public static Expression<Func<T, bool>> PredicateExtension<T>(this IQueryable<T> source, string member, object value, string expression)
{
ParameterExpression item = Expression.Parameter(typeof(T), "item");
Expression memberValue = member.Split('.').Aggregate((Expression)item, Expression.PropertyOrField);
Type memberType = memberValue.Type;
if (value != null && value.GetType() != memberType)
value = Convert.ChangeType(value, memberType);
Expression condition = null;
switch (expression)
{
case "==":
condition = Expression.Equal(memberValue, Expression.Constant(value, memberType));
break;
case "!=":
condition = Expression.NotEqual(memberValue, Expression.Constant(value, memberType));
break;
case "<":
condition = Expression.LessThan(memberValue, Expression.Constant(value, memberType));
break;
case ">":
condition = Expression.GreaterThan(memberValue, Expression.Constant(value, memberType));
break;
case "<=":
condition = Expression.LessThanOrEqual(memberValue, Expression.Constant(value, memberType));
break;
case ">=":
condition = Expression.GreaterThanOrEqual(memberValue, Expression.Constant(value, memberType));
break;
default:
break;
}
if (condition == null)
condition = Expression.Equal(memberValue, Expression.Constant(value, memberType));
var predicate = Expression.Lambda<Func<T, bool>>(condition, item);
return predicate;
}
現在用以下參數調用方法時:
LinqExtentions.PredicateExtension<OptionalSite>(SiteDbSet, "SiteId", 1, "==");
我有以下問題:在方法的第二行有一個Aggregate
調用,但這給了我AmbiguousMatchException
。 原因是屬性SiteId
既定義在基類中,也定義在OptionalSite
類中(public new ...)...
所以這里的問題是:如何使用這種(或另一種)方法獲得正確的表達式? 我可能需要獲得相同的Expression
結果,但使用不同的獲取方式,以便在基類中找到屬性時,我可以為實現基類的類選擇實現的類。
編輯:
SiteId
的類型從int
更改為int?
。 實現此基類的其他類需要將其作為必需屬性(EF),但此類需要它作為可選屬性。 因此我不能在我的基類中使用virtual
關鍵字。
有關為何獲得AmbiguousMatchException
以及如何解決它的信息,您可以查看此答案。
您必須使用更高級的功能:
Expression memberValue = member.Split('.').Aggregate((Expression)item, (expr, name) =>
{
// get all properties with matching name
var properties = expr.Type.GetProperties().Where(p => p.Name == name);
// if only one found, use that, else use the one that is declared in the derived type
var property = properties.Count() == 1 ? properties.First() : properties.Single(p => p.DeclaringType == expr.Type);
// make expression from this PropertyInfo
return Expression.Property(expr, property);
});
請注意,這只是一種基本方法。 它不考慮字段(不應該是EF的問題),並且可能存在多個級別的繼承,其中聲明的屬性介於兩者之間。 但是你明白了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.