大家早上好,我有一个关于linq到sql的问题 . 特别是“动态Linq” . 我正在尝试创建一个搜索功能,用户可以在其中输入任何字符串,并过滤所有字段,包括DateTime字段 .
所以说DateTime存储的是“10/11/2015”,当用户键入“10”时我希望记录返回 .
所以类似于:
x=> x.dateTime.ToString("dd/mm/yyyy").Contains("10")
但这不起作用,因为sql没有ToString方法 .
为了使这个问题更有趣,所有这些都是通用的 . 所以我收到必须作为字符串列表搜索的属性,我收到类型为T,我收到搜索字符串作为字符串 .
因此,如果我只是在属性“dateTime”中查找“10”,即如果T是泛型类型,那么我将如何编写搜索表达式 .
ConstantExpression searchArgument = Expression.Constant("10");
ParameterExpression param = Expression.Parameter(typeof(T), "x");
// Get Property, even if nested property.
Expression property = "dateTime".Split('.').Aggregate<string, Expression>(param, Expression.Property);
// Get Contains method for property type
MethodInfo containsMethod = typeof(String).GetMethod("Contains");
// Convert the property if necessary.
MethodInfo convertMethod = null;
if (TypeExtensions.IsNumericType(property.Type))
{
convertMethod = typeof(SqlFunctions).GetMethod("StringConvert", new[] { typeof(double?) });
if (convertMethod != null)
{
property = Expression.Call(convertMethod, Expression.Convert(property, typeof(double?)));
}
}
else if (property.Type == typeof(DateTime))
{
throw new NotImplementedException();
// TODO - How do I write a convertion method here to convert the DateTime property to a string as "dd/mm/yyyy"?
convertMethod = null;
if (convertMethod != null)
{
property = Expression.Call(convertMethod, Expression.Convert(property, typeof(DateTime?)));
}
}
MethodCallExpression fieldExpression = Expression.Call(property, containsMethod, searchArgument);
// Create the contains expression
Expression<Func<T, bool>> searchExpression = Expression.Lambda<Func<T, bool>>(fieldExpression, param);
这适用于字符串和数字但不适用于DateTimes,任何人都可以帮忙吗?提前致谢!
2 回答
我需要对此进行双重检查,但根据https://msdn.microsoft.com/en-us/library/bb738681.aspx,
Day
,Month
和Year
应该可以正常工作,因此您可以执行以下操作:我记得EF在整数上理解
ToString()
,虽然我'm not sure, but if it doesn',上面使用SqlFunctions.StringConvert
,而不是ToString()
或者你可以使用
SqlFunctions
而不是调用ToString
自己创建字符串,类似于:您还可以按组件进行比较,检查日,月或年是否等于您传递的变量 . 我不知道你是否也愿意 . 例如,如果用户像“1”那样返回所有日期包含1的记录,但我也不建议,如果你的数据库有一些维度,你会返回很多记录