我使用EF5有一个由字符串,日期,可空日期和整数组成的大型20个属性实体。是否可以使用Linq对每个字段进行包含。
我不想为每个字段构建一个linq语句
results = list.Where(house => house.Date1.ToString().Contains(search)||
house.Address1.Contains(search)||
house.Address2.Contains(search)||
house.Address3.Contains(search)||
.........................)
我想我想将所有属性转换为字符串(必要时),然后对每个属性进行包含?理想情况下,这将发生在数据库级别。
我想我无法连接它们,因为如果两个字段的结束和开始创建搜索文本,它可能会导致错误匹配?有什么想法吗?
我目前是这个LINQ string[] against multiple fields使用LinqKit AsExpandable和EF转换函数根据类型进行字符串的第二个答案。但是我似乎无法找到将DateTime转换为字符串
的SqlFunction答案 0 :(得分:3)
因此,这里的一般想法是使用PredicateBuilder
将OR表示一组表达式,每个表达式代表对给定属性的Contains
检查。您可以使用反射来查找给定类型的所有属性,以便为。
public static Expression<Func<T, bool>> SearchAllFields<T>(string searchText)
{
var t = Expression.Parameter(typeof(T));
Expression body = Expression.Constant(false);
var containsMethod = typeof(string).GetMethod("Contains"
, new[] { typeof(string) });
var toStringMethod = typeof(object).GetMethod("ToString");
var stringProperties = typeof(T).GetProperties()
.Where(property => property.PropertyType == typeof(string));
foreach (var property in stringProperties)
{
var stringValue = Expression.Call(Expression.Property(t, property.Name),
toStringMethod);
var nextExpression = Expression.Call(stringValue,
containsMethod,
Expression.Constant(searchText));
body = Expression.OrElse(body, nextExpression);
}
return Expression.Lambda<Func<T, bool>>(body, t);
}
答案 1 :(得分:1)
我最近创建了一个nuget包,使用扩展方法解决了这个问题
这将允许以下代码......
using NinjaNye.SearchExtensions;
//...
var result = list.Search(h => search, h.Date1.ToString(),
h.Address1,
h.Address2,
h.Address3,
...etc...)
如果要使用代码,请查看github页面: https://github.com/ninjanye/SearchExtensions
当连接到sql数据库时,你得到类似于以下sql的东西:
SELECT [Extent1].[Date1] AS [Date1],
[Extent1].[Address1] AS [Address1],
[Extent1].[Address2] AS [Address2],
[Extent1].[Address3] AS [Address3]
FROM [dbo].[Table] AS [Extent1]
WHERE ([Extent1].[Address1] LIKE N'%searchTerm%')
OR ([Extent1].[Address2] LIKE N'%searchTerm%')
OR ([Extent1].[Address3] LIKE N'%searchTerm%')
希望这有帮助