簡體   English   中英

C#Aggregate for property Expression返回AmbiguousMatchException

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM