C# 类似于使用动态lambda表达式搜索日期时间字段
我正在形成如下所示的字符串表达式C# 类似于使用动态lambda表达式搜索日期时间字段,c#,asp.net-mvc,linq,lambda,C#,Asp.net Mvc,Linq,Lambda,我正在形成如下所示的字符串表达式 string Condition = " it.person_id = " + personId.ToString(); if (lstPersonFields != null) { foreach (var field in lstPersonFields ) { string fieldConditio
string Condition = " it.person_id = " + personId.ToString();
if (lstPersonFields != null)
{
foreach (var field in lstPersonFields )
{
string fieldCondition = " And it." + field.FieldName.ToString();
if (field.FieldCondition == "Contains")
{
fieldCondition = fieldCondition + " Like '%" + field.FieldValue.ToString() + "%'";
}
else if (field.FieldCondition == "Equals")
{
fieldCondition = fieldCondition + " = '" + field.FieldValue.ToString()+"'";
}
Condition = Condition + fieldCondition;
}
}
var personSearch = FullPersonlst.Where(Condition).ToList();
上述代码在like搜索中对除datetime值以外的其他值正常工作,并对datetime字段抛出错误,如
Like arguments must be of string type
如何对datetime字段执行like搜索?正如错误所述,不应将like用于非字符串值。这也毫无意义。如果要搜索特定的日期时间,请使用datetime=value。用于在可在之间使用的时间范围内搜索。您需要检查要搜索的属性的类型,并在查询中使用适当的方式拟合该类型
就我个人而言,我永远不会使用这样的“动态查询创建者” 作为动态lambda表达式执行此操作的方式如下:
var arg = Expression.Parameter(typeof(Person), "it");
var body = Expression.Equal(
Expression.PropertyOrField(arg, "PersonId"),
Expression.Constant(personId));
if (lstPersonFields != null)
{
foreach (var field in lstPersonFields)
{
var member = Expression.PropertyOrField(arg, field.FieldName);
switch (field.FieldCondition)
{
case "Contains":
body = Expression.AndAlso(body,
Expression.Call(typeof(SqlMethods), "Like", null,
member,
Expression.Constant("%" + field.FieldValue + "%")));
break;
case "Equals":
body = Expression.AndAlso(body,
Expression.Equal(
member,
Expression.Constant(field.FieldValue)));
break;
}
}
}
var lambda = Expression.Lambda<Func<Person,bool>>(body, arg);
var personSearch = FullPersonlst.Where(lambda).ToList();
var arg=Expression.Parameter(typeof(Person),“it”);
var body=表达式。等于(
Expression.PropertyOrField(arg,“PersonId”),
表达式.常量(personId));
if(lstPersonFields!=null)
{
foreach(lstPersonFields中的var字段)
{
var member=Expression.PropertyOrField(arg,field.FieldName);
开关(现场条件)
{
案例“包含”:
body=表达式AndAlso(body,
Call(typeof(SqlMethods),“Like”,null,
委员:,
表达式.常量(“%”+field.FieldValue+“%”);
打破
案例“等于”:
body=表达式AndAlso(body,
表达式。相等(
委员:,
表达式.Constant(field.FieldValue));
打破
}
}
}
var lambda=表达式.lambda(body,arg);
var personSearch=FullPersonlst.Where(lambda.ToList();
您是否尝试将datetime转换为字符串..?我认为在这种情况下不可能,因为我们不知道字段名。不要连接输入。重复:不要连接输入。这是非常危险的代码…@User\u MVC,因为它非常容易受到SQL注入的影响。如果您不熟悉SQL注入,请立即查找它。这是非法获取数据和销毁数据的最普遍方式。如果您经常编写上述代码,那么您的系统将从根本上崩溃,需要立即关注。当我将上述代码转换为LINQ to Entities时,它会抛出这样的错误:LINQ to Entities无法识别方法“Boolean like(system.String,system.String)”方法,并且此方法无法转换为存储表达式。该版本(SqlMethods
)是LINQ to SQL-因此它可能无法在EF中工作;您也可以只使用包含
-即表达式.Call(成员,“包含”、null、表达式.Constant(field.FieldValue))
,或者使用更多选项,请参见此处:@Marc Gravell:上面的代码不适用于日期时间值。似乎需要对代码进行一些更改。您能否告诉我如何修改此代码以适用于日期时间值。@用户可以添加一些表达式。转换(为字符串)或表达式。调用“ToString”。或者获取DateTime输入,只需使用Equal etc@Marc我喜欢这个系统。Reflection.PropertyInfo prop=typeof(vw_directory_search)。GetProperty(field.FieldName);body=Expression.AndAlso(body,Expression.Call(成员,“等于”,null,Expression.Convert(Expression.Constant(field.FieldValue),prop.PropertyType));但它会抛出以下错误:在类型“System.String”和“System.Nullable`1[System.DateTime]”之间未定义强制运算符。