算在哪里?

是否可以在哪里使用列表。 我想要这样的想法:

public class Customer { string FirtsName; string LastName; int Number; ..... } 

我想使用复选框过滤客户。 如果我选择FirstName和Number,那么将生成where子句

 .where(x=> x.FirstName == "SomeFirstName" && x.Number == someNumber) 

如果我只选择数字,那么将生成where子句

 .where(x.Number == someNumber) 

如果我选择FirstName,LastName和Number,那么将生成where子句

 .where(x=> x.FirstName == "SomeFirstName" && x.Number == someNumber && x.LastName == "LastName") 

我的意思不仅是动态列名,我也想生成where子句。 列名和值来自列表:

我希望,我可以解释一下。 提前致谢。

您可以试试Dynamic LINQ 。 有了这个,你可以这样写:

 var db = new NorthwindDataContext; var query = db.Products.Where("CategoryID=2 And UnitPrice>3").OrderBy("SupplierId"); 

使用多一步来生成查询:

 var query = originalList.AsQueryable(); if(/*Filtering on First Name*/) { query = query.where(x => x.FirstName == FirstNameSearchString); } if(/*Filtering on Last Name */) { query = query.where(x => x.LastName == LastNameSearchString); } if(/*Filtering on Number*/) { query = query.where(x => x.Number== NumberSearchString); } //..And so on //Do stuff with query 

如果您不想执行多个if语句,我可以考虑另外两种方法:

  • 手动构建自己的表达式树:

表达式树(C#和Visual Basic) 如何:使用表达式树来构建动态查询(C#和Visual Basic)

另一种方法是创建一个复杂的where子句,如果选择了此列searc选项,则使用AND和OR仅过滤:

.where(x =>(IsFirstNameFilter == true && x.FirstName = FirstNameData)||(IsLastNameFilter == true && x.LastName = LastNameData)|| …);

有了这个,你需要小心执行时间,连接SQL事件探查器,看看发生了什么。

我仍然推荐第一个选项。

我认为上面的答案中的第一个建议是好的 – 我在我当前的架构中有效地做了同样的事情,但它包含了更多,从根本上分为两部分:

  1. 我有一个filter类(特定于任何相关实体……在你的情况下,可能会被称为“CustomerFilter”)这个类有一个看起来像这样的方法(只是一个例子)

     public class CustomerFilters { public IEnumerable>> Filters() { if (/*check if should filter on FirstName here*/) { yield return cust => cust.FirstName == FirstNameSearchString; } if (/*check if should filter on Surname here*/) { yield return cust => cust.Surname == SurnameSearchString; } } } 
  2. 我有一个扩展方法(作为帮助程序,不一定必须是一个扩展方法),它基本上遍历所有filter并构建它的位置。 代码看起来像这样(或多或少):

     public static IQueryable Filter(this IQueryable collection, IEnumerable>> filters) { var results = collection; foreach (var f in filters) { results = results.Where(f); } return results; } 

然后,它的用法可能如下所示:

 var query = db.Customers.Filter(myCustomerFilterClass.Filters()); 

就像我说的那样,它与前一个答案相同(为了简洁起见,我在这里简化了很多代码),但我发现将它包装起来并以这种方式对其进行抽象是非常有用的。应用程序中有许多filter,许多实体,以及要应用的特定filter是用户驱动的。

我会避免使用字符串,因为你会失去类型安全性。 相反,我会使用表达式树来构建where子句的表达式。

  //The variable name for the parameter expression must match in all others var parameter = Expression.Parameter(typeof(Customer),"c"); Expression> firstNameCheck = c => c.FirstName == FirstNameSearchString; Expression> lastNameCheck = c => c.LastName == LastNameSearchString; Expression> numberCheck = c => c.Number.ToString() == NumberSearchString; //Default to a true expression Expression ongoingExpression = Expression.Constant(true); if (//Filter on first name) { ongoingExpression = Expression.AndAlso(ongoingExpression, Expression.Invoke(firstNameCheck, parameter)); } if (//Filter on last name) { ongoingExpression = Expression.AndAlso(ongoingExpression, Expression.Invoke(lastNameCheck, parameter)); } if (//Filter on number) { ongoingExpression = Expression.AndAlso(ongoingExpression, Expression.Invoke(numberCheck, parameter)); } var lambda = Expression.Lambda>(ongoingExpression, parameter); query = query.Where(lambda.Compile());