簡體   English   中英

IQueryable表達式類型不匹配

[英]IQueryable expression type mismatch

我想為LINQ表達式創建擴展方法,但是我遇到了麻煩。 我需要的只是創建一個將特定的Where子句添加到Queryable 就像是:

var hierarchy = "a string";
Session.Query<SomeClass>.Where(x => x.Layer.Hierarchy.StartsWith(hierarchy) ||
                                    x.Layer.Hierarchy == hierarchy);

成為:

var hierarchy = "a string";
Session.Query<SomeClass>.LayerHierarchy(x => x.Layer, hierarchy);

並執行其中的邏輯。 因此,基本上,擴展方法LayerHierarchy()TQueryable之上運行,但是主題的類型為Layer

public static IQueryable<T> LayerHierarchy<T>(this IQueryable<T> query,
                                                  Expression<Func<T, Layer>> layer,
                                                  string hierarchy)

{
    var parameterExp = Expression.Parameter(typeof(Layer), "layer");
    var propertyExp = Expression.Property(parameterExp, "Hierarchy");

    // StartWith method
    MethodInfo methodStartsWith = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
    var valueStartsWith = Expression.Constant(string.Concat(hierarchy, "|"), typeof(string));

    var methodExpStartsWith = Expression.Call(propertyExp, methodStartsWith, valueStartsWith);
    var startsWith = Expression.Lambda<Func<Layer, bool>>(methodExpStartsWith, parameterExp);

    // Equals method
    MethodInfo methodEquals = typeof(string).GetMethod("Equals", new[] { typeof(string) });
    var valueEquals = Expression.Constant(hierarchy, typeof(string));

    var methodExpEquals = Expression.Call(propertyExp, methodEquals, valueEquals);
    var equals = Expression.Lambda<Func<Layer, bool>>(methodExpEquals, parameterExp);

    return query
                .Where(startsWith)
                .Where(equals);
}

return線以上,一切正常。 它抱怨...

無法從System.Linq.Expressions.Expression<System.Func<Layer, bool>>System.Linq.Expressions.Expression<System.Func<T, int, bool>>

嘗試將表達式傳遞給query.Where()方法時。 我該如何解決?

好吧,問題在於您如何創建Lambda 它們應該從T開始,而不是從Layer

var startsWith = Expression.Lambda<Func<T, bool>>(methodExpStartsWith, parameterExp);
var equals = Expression.Lambda<Func<T, bool>>(methodExpEquals, parameterExp);

但是,為了使其正常工作,您還缺少一個PropertyExpression

您的查詢現在看起來像:

(層)x => x.Hierarchy.StartsWith(...)

什么時候,您想要的是:

(T)x => x.Layer.Hierarchy.StartsWith(...)

因此,請改用此:

var parameterExp = Expression.Parameter(typeof(T), "item");
var layerExp = Expression.Property(parameterExp, "Layer");
var propertyExp = Expression.Property(layerExp, "Hierarchy");

但是,您的邏輯應該稍有變化,因為兩個.Where會在它們之間生成一個AND條件,並且似乎您希望其中一個為真( StartsWithEquals ),因此:

var parameterExp = Expression.Parameter(typeof(T), "item");
var layerExp = Expression.Property(parameterExp, "Layer");
var propertyExp = Expression.Property(layerExp, "Hierarchy");

// StartWith method
MethodInfo methodStartsWith = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
var valueStartsWith = Expression.Constant(string.Concat(hierarchy, "|"), typeof(string));

var methodExpStartsWith = Expression.Call(propertyExp, methodStartsWith, valueStartsWith);

// Equals method
MethodInfo methodEquals = typeof(string).GetMethod("Equals", new[] { typeof(string) });
var valueEquals = Expression.Constant(hierarchy, typeof(string));

var methodExpEquals = Expression.Call(propertyExp, methodEquals, valueEquals);

var orElseExp = Expression.OrElse(methodExpStartsWith, methodExpEquals);
var orElse = Expression.Lambda<Func<T, bool>>(orElseExp, parameterExp);

return query.Where(orElse);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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