来自查询的动态表达式,表达式调用

时间:2016-04-04 10:36:11

标签: c# entity-framework linq-to-sql lambda expression-trees

Hy,在我的代码中,我有一个构建' where表达式'的方法。它看起来像这样:

private static Expression<Func<T, bool>> BuildWhereExpression<T>(Context context, string memberName, string memberValue)
{
    memberValue = memberValue.Trim().RemoveDiacritics().ToLower();

    var param = Expression.Parameter(typeof(T), "x");

    var propsNames = memberName.Split('.');
    Expression propExpression = param;
    foreach (var propName in propsNames)
    {
        propExpression = Expression.Property(propExpression, propName);
    }

    var methodToLower = typeof(string).GetMethods().First(x => x.Name == "ToLower" && x.GetParameters().Length == 0);
    var toLowerCall = Expression.Call(propExpression, methodToLower);

    var methodDiacritics = typeof(context).GetMethod("GetStringWithoutDiacritics");
    var funcCall = Expression.Call(Expression.Constant(context), methodDiacritics, toLowerCall);

    var methodContains = typeof(string).GetMethods().First(x => x.Name == "Contains" && x.GetParameters().Length == 1);
    var containsCall = Expression.Call(funcCall, methodContains, Expression.Constant(memberValue));

    var lambda = Expression.Lambda<Func<T, bool>>(containsCall, param);

    return lambda;
}

其中&#34; GetStringWithouDiacritics&#34;是我的数据库中的标量函数(代码优先)。当与&#39; Where&#39;一起使用时,这会产生下列内容。 :

WHERE ([dbo].[GetStringWithoutDiacritics](LOWER([Extent2].[Col1])) LIKE N'%blabla%')

这没关系,但因为我在性能非常糟糕的情况下使用标量函数。我想要做的是在函数&#39; inline&#39;中编写sql代码。它应该产生类似的东西:

WHERE CONVERT(VARCHAR(MAX),REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(LOWER(Col1) COLLATE Latin1_General_BIN, N'ș','s') COLLATE Latin1_General_BIN, N'ț','t') COLLATE Latin1_General_BIN, N'î', 'i') COLLATE Latin1_General_BIN, N'ă', 'a') COLLATE Latin1_General_BIN, N'â', 'a'))
                                     LIKE '%parite%'

我的问题是我如何修改构建where表达式的方法。我知道这是动态表达,但我无法弄清楚如何... ,以取代Col1&#39;用我的实际专栏等。

1 个答案:

答案 0 :(得分:0)

你使用什么数据库?在MSSQL中,您可以以可以内联的方式定义函数。我会先探索那种方式。

如果这对你不起作用,那么这里有一个关于如何很好地组合表达式树的答案link。在这种情况下,您可以删除标量函数,并完全在C#中定义您的方法。