不区分大小写的lambda表达式
本文关键字:lambda 表达式 大小写 不区 | 更新日期: 2023-09-27 18:09:36
我正在使用Visual Studio 2015, Entity Framework 6,并试图构建一个LINQ表达式来获取基于动态WHERE
子句的结果。用户可以选择搜索"employeeId
"、"securityId
"(字符串)或"lastName
"。对于姓氏,它应该执行不区分大小写的搜索,因此用户可以输入大写或小写的searchValue
。
这是我得到的:
public async Task<ObservableCollection<EmployeeViewModel>>
SearchEmployeesAsync(string selectedColumn, string searchValue)
{
var paramEmployee = Expression.Parameter(typeof(Employee), "e");
Func<EmployeeBase, bool> comparison = null;
if (selectedColumn.Equals("employeeId"))
{
var employeeId = -1;
int.TryParse(searchValue, out employeeId);
comparison = Expression.Lambda<Func<Employee, bool>>(
Expression.Equal(
Expression.Property(paramEmployee, selectedColumn),
Expression.Constant(employeeId)),
paramEmployee).Compile();
}
else
{
comparison = Expression.Lambda<Func<Employee, bool>>(
Expression.Equal(
Expression.Property(paramEmployee, selectedColumn),
Expression.Constant(searchValue)),
paramEmployee).Compile();
}
using (var context = new MyEntities())
{
var query = (from e in context.Employees
.Where(comparison)
select new EmployeeViewModel
{
// Populate view model from entity object here
});
return await Task.Run(() => new ObservableCollection<EmployeeViewModel>(query));
}
}
如何更改上述代码,使comparison
对securityId
或lastName
(两者都是数据库上的字符串)的搜索不区分大小写?securityId
或lastName
由上面的else
块覆盖。如果有更好的方法,我也愿意重构代码。我不想做的一件事是使用第三方库来编写动态WHERE
子句。
谢谢。
如果希望在数据库中而不是在内存中应用过滤,则必须在Where
子句中使用Expression<Func<Employee, bool>>
,而不是在代码中使用Func<Employee, bool>
。使用ToLower
方法可以模拟不区分大小写的比较。
另外,正如其他人提到的那样,通过使用System.Data.Linq.QueryableExtensions
中的ToListAsync
方法来消除Task.Run
调用会更好。
话虽如此,实现可能是这样的:
using System.Data.Entity;
public async Task<ObservableCollection<EmployeeViewModel>>
SearchEmployeesAsync(string selectedColumn, string searchValue)
{
var parameter = Expression.Parameter(typeof(T), "e");
Expression left = Expression.PropertyOrField(parameter, selectedColumn);
object value = searchValue;
if (selectedColumn == "employeeId")
{
var employeeId = -1;
int.TryParse(searchValue, out employeeId);
value = employeeId;
}
else
{
// case insensitive
left = Expression.Call(left, "ToLower", Type.EmptyTypes);
value = searchValue.ToLower();
}
var comparison = Expression.Lambda<Func<T, bool>>(
Expression.Equal(left, Expression.Constant(value)),
parameter);
using (var context = new MyEntities())
{
var query = context.Employees
.Where(comparison)
.Select(e => new EmployeeViewModel
{
// Populate view model from entity object here
});
var result = await query.ToListAsync();
return new ObservableCollection<EmployeeViewModel>(result);
}
}
我建议用简单的方法。我质疑这个任务。跑,但因为这不是问题的一部分,所以我不去管它。
public async Task<ObservableCollection<EmployeeViewModel>>
SearchEmployeesAsync(string selectedColumn, string searchValue)
{
using (var context = new MyEntities())
{
var query = context.Employees.AsQueryable();
switch(selectedColumn)
{
case "employeeId":
var employeeId = -1;
int.TryParse(searchValue, out employeeId);
query = query.Where(e=>e.employeeId == employeeId);
break;
case "lastName":
query = query.Where(e=>e.lastName == searchValue);
break;
case "securityId":
query = query.Where(e=>e.securityId == searchValue);
break;
}
query = query.Select(e=> new EmployeeViewModel
{
// Populate view model from entity object here
});
return await Task.Run(() => new ObservableCollection<EmployeeViewModel>(query));
}
}