gpt4 book ai didi

c# - 是否可以在 Lambda 表达式中包含 SqlFunctions.StringConvert?

转载 作者:行者123 更新时间:2023-11-30 15:36:37 25 4
gpt4 key购买 nike

我一直在学习表达式并使用下面的代码添加构建针对数据库模型的表达式(EF4 - ORACLE 而不是 SQL!)

这对 Oracle 非常有效,并允许我动态地构建谓词,例如 "CustomerId", "Contains", 2f=>f.CustomerId.ToString() 中。 ToLower().Contains("2")

但是,如果我尝试针对 SQL Server 然后它会失败,因为我需要调用 SqlFunctions.StringConvert - 但我不知道如何将其包含在 Lambda 中?

我的最终结果是这样的:

f=> SqlFunctions.StringConvert(f.CustomerId).ToLower().Contains("2")

谢谢 :)


编辑:添加了我尝试过的示例

这段代码看起来几乎可以工作了,有点!
但是,它会在 var sqlExpression

上抛出错误
Expression of type 'System.Double' cannot be used for parameter of type 'System.Nullable`1[System.Double]' of method 'System.String StringConvert(System.Nullable`1[System.Double])'


MethodInfo convertDouble = typeof(Convert).GetMethod("ToDouble",new Type[]{typeof(int)});
var cExp = Expression.Call(convertDouble, left.Body);

var entityParam = Expression.Parameter(typeof(TModel), "f");
MethodInfo sqlFunc = typeof(SqlFunctions).GetMethod("StringConvert", new Type[] { typeof(double) });
var sqlExpression = Expression.Call(sqlFunc, cExp);


MethodInfo contains = typeof(string).GetMethod("Contains", new[] { typeof(string) });
right = Expression.Constant(value.ToString(), typeof(string));

var result = left.AddToString().AddToLower().AddContains(value.ToString());
return result;

public static Expression<Func<T, string>> AddToString<T, U>(this Expression<Func<T, U>> expression)
{

return Expression.Lambda<Func<T, string>>(
Expression.Call(expression.Body,
"ToString",
null,
null),
expression.Parameters);
}

public static Expression<Func<T, string>> AddToLower<T>(this Expression<Func<T, string>> expression)
{

return Expression.Lambda<Func<T, string>>(
Expression.Call(expression.Body,
"ToLower",
null,
null),
expression.Parameters);
}

public static Expression<Func<T, bool>> AddContains<T>(this Expression<Func<T, string>> expression, string searchValue)
{
return Expression.Lambda<Func<T, bool>>(
Expression.Call(
expression.Body,
"Contains",
null,
Expression.Constant(searchValue)),
expression.Parameters);
}

最佳答案

我相信您基本上需要构建以下 lambda 表达式的等效表达式:

e => SqlFunctions.StringConvert((double?) e.Number).Contains("6"))

这是一个完整的复制粘贴示例。它使用 CodeFirst,因此无需创建数据库或类似的东西就可以工作。只需添加 Entity Framework nuget 包(我使用 EF6,但它也适用于 EF5)。构建 lambda 才是您真正想要的。

namespace ConsoleApplication8
{
public class MyEntity
{
public int Id { get; set; }
public int Number { get; set; }
}


public class MyContext : DbContext
{
public DbSet<MyEntity> Entities { get; set; }
}

class Program
{
static void Main(string[] args)
{
using (var ctx = new MyContext())
{
if (!ctx.Entities.Any())
{
ctx.Entities.Add(new MyEntity() {Number = 123});
ctx.Entities.Add(new MyEntity() {Number = 1893});
ctx.Entities.Add(new MyEntity() {Number = 46});
ctx.SaveChanges();
}

foreach(var entity in ctx.Entities.Where(e => SqlFunctions.StringConvert((double?) e.Number).Contains("6")))
{
Console.WriteLine("{0} {1}", entity.Id, entity.Number);
}

foreach (var entity in ctx.Entities.Where(BuildLambda<MyEntity>("Number", "6")))
{
Console.WriteLine("{0} {1}", entity.Id, entity.Number);
}

}
}

private static Expression<Func<T, bool>> BuildLambda<T>(string propertyName, string value)
{
var parameterExpression = Expression.Parameter(typeof(T), "e");

var stringConvertMethodInfo =
typeof(SqlFunctions).GetMethod("StringConvert", new Type[] {typeof (double?)});

var stringContainsMethodInfo =
typeof (String).GetMethod("Contains");

return
Expression.Lambda<Func<T, bool>>(
Expression.Call(
Expression.Call(
stringConvertMethodInfo,
Expression.Convert(
Expression.Property(parameterExpression, "Number"),
typeof (double?))),
stringContainsMethodInfo,
Expression.Constant(value)),
parameterExpression);
}
}
}

关于c# - 是否可以在 Lambda 表达式中包含 SqlFunctions.StringConvert?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13577981/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com