我希望能够重构linq表达式中的 OrderBy 子句。
以下是 where 子句
的重构示例之前:
results = ctx.ActiveUsers
.Where(u => u.CompanyID != 1 &&
(u.LastName.ToLower().Contains(searchString)
|| u.Email.ToLower().Contains(searchString)
|| u.Company.Name.ToLower().Contains(searchString)))
.OrderBy(u => u.LastName ).ThenBy(u => u.FirstName)
.Select(u => new Employee {
ID = u.ID
, FirstName = u.FirstName
, LastName = u.LastName
, Email = u.Email
, CompanyName = u.Company.Name
, CompanyID = u.CompanyID.ToString() });
后:
results = ctx.ActiveUsers
.Where(Employee.GetExpression(searchString))
.OrderBy(u => u.LastName ).ThenBy(u => u.FirstName)
.Select(u => new Employee {
ID = u.ID
, FirstName = u.FirstName
, LastName = u.LastName
, Email = u.Email
, CompanyName = u.Company.Name
, CompanyID = u.CompanyID.ToString() });
private static Expression<Func<User, bool>> GetExpression(string searchString)
{
Expression<Func<User, bool>> p = (u => u.CompanyID != 1 &&
(u.LastName.ToLower().Contains(searchString)
|| u.Email.ToLower().Contains(searchString)
|| u.Company.Name.ToLower().Contains(searchString)));
return p;
}
我想知道是否可以使用相同类型的东西,除非我想重构 Orderby 表达式。
提前谢谢
答案 0 :(得分:3)
假设您想要实际使用“LastName”,“FirstName”等字符串,我会做类似的事情:
var unordered = ctx.ActiveUsers
.Where(Employee.GetExpression(searchString))
.OrderBy(ordering)
.Select(u => new Employee {
ID = u.ID,
FirstName = u.FirstName,
LastName = u.LastName,
Email = u.Email,
CompanyName = u.Company.Name,
CompanyID = u.CompanyID.ToString() });
并添加一个新的OrderBy扩展方法:
public static class UserQueryableExtensions
{
public static IOrderedQueryable<User> OrderBy(this IQueryable<User> source,
string ordering)
{
switch (ordering)
{
case "LastName":
return source.OrderBy(x => x.LastName);
case "FirstName":
return source.OrderBy(x => x.FirstName);
case "Email":
return source.OrderBy(x => x.Email);
case "Company":
return source.OrderBy(x => x.Company);
default:
throw new ArgumentException("Unknown ordering");
}
}
}
你当然可以使用反射来做到这一点,但除非你有一组重要的属性(或者你想对不同的实体类型使用相同的例程),否则switch语句会更容易。
答案 1 :(得分:1)
感谢jon,
这个答案让我现在正走在正确的道路上......但是, 我需要在订单中保留 ThenBy 子句。因此,虽然下面的解决方案不是动态的,但它仍保留 ThenBy
var unordered = ctx.ActiveUsers
.Where(Employee.GetExpression(searchString))
.MyOrder()
.Select(u => new Employee {
ID = u.ID,
FirstName = u.FirstName,
LastName = u.LastName,
Email = u.Email,
CompanyName = u.Company.Name,
CompanyID = u.CompanyID.ToString() });
public static class UserQueryableExtensions
{
public static IOrderedQueryable<User> MyOrder(this IQueryable<User> source )
{
return source.OrderBy(x => x.LastName).ThenBy(x => x.FirstName).ThenBy(x => x.Email);
}
}
答案 2 :(得分:0)
我同意Jon在可能的情况下使用lambdas来避免错别字等。但是,如果你真的不能这样做(无论出于何种原因),我已经看过了充满活力的OrderBy
过去。有关在LINQ-to-SQL上测试的示例,请参阅here(但理论上它应该适用于EF)。