我已经弄清楚如何用linq对sql进行条件查询,我也想出了如何在OR where子句中。不幸的是,我无法弄清楚如何同时做两件事。我可以做一个条件where子句,如:
var ResultsFromProfiles = from AllPeeps in SearchDC.aspnet_Users
select AllPeeps;
if (SearchFirstNameBox.Checked)
{
ResultsFromProfiles = ResultsFromProfiles.Where(p => p.tblUserProfile.FirstName.Contains(SearchTerm));
}
if (SearchLastNameBox.Checked)
{
ResultsFromProfiles = ResultsFromProfiles.Where(p => p.tblUserProfile.LastName.Contains(SearchTerm));
}
这将为我提供任何配置文件,其中名字和姓氏包含搜索词。
或者我能做到:
var ResultsFromProfiles = from p in SearchDC.aspnet_Users
where p.tblUserProfile.LastName.Contains(SearchTerm) ||
p.tblUserProfile.FirstName.Contains(SearchTerm)
select p;
这将为我提供任何配置文件,其中名字或姓氏包含搜索词。
我有一堆复选框,用户可以在其中指定要搜索哪些字段的搜索字词,因此我希望能够构建一个有条件地添加它们的查询,就像在上面的第一个代码段中一样,但是添加它们作为OR,所以它们像第二个片段一样工作。这样,它将搜索指定字段中任何位置的任何匹配项。
任何提示?
答案 0 :(得分:4)
是的,请使用PredicateBuilder。它允许您使用And或Or语义构建动态查询。它是免费且稳定的 - 我在整个地方都使用它。
答案 1 :(得分:1)
执行此操作的一种方法是为查询操作LINQ表达式树。在您的情况下,您需要构建一个lambda表达式并将其替换为对Where
的调用。这是一个基于列表的工作示例,但无论查询提供程序如何,操作表达式树的代码都是相同的。
List<User> Users = new List<User>();
Users.Add(new User() { FirstName = "John", LastName = "Smith" });
Users.Add(new User() { FirstName = "Jane", LastName = "Smith" });
string Query = "John";
var Queryable = Users.AsQueryable();
var Results = (from u in Queryable
select u);
//initial method call... the lambda u => false is a place-holder that is about to be replaced
MethodCallExpression WhereExpression = (MethodCallExpression)Results.Where(u => false).Expression;
//define search options
Expression<Func<User, string, bool>> FilterLastName = (u, query) => u.LastName.Contains(query);
Expression<Func<User, string, bool>> FilterFirstName = (u, query) => u.FirstName.Contains(query);
//build a lambda based on selected search options... tie the u parameter to UserParameter and the query parameter to our Query constant
ParameterExpression UserParameter = Expression.Parameter(typeof(User), "u");
Expression Predicate = Expression.Constant(false); //for simplicity, since we're or-ing, we'll start off with false || ...
//if (condition for filtering by last name)
{
Predicate = Expression.Or(Predicate, Expression.Invoke(FilterLastName, UserParameter, Expression.Constant(Query)));
}
//if (condition for filtering by first name)
{
Predicate = Expression.Or(Predicate, Expression.Invoke(FilterFirstName, UserParameter, Expression.Constant(Query)));
}
//final method call... lambda u => false is the second parameter, and is replaced with a new lambda based on the predicate we just constructed
WhereExpression = Expression.Call(WhereExpression.Object, WhereExpression.Method, WhereExpression.Arguments[0], Expression.Lambda(Predicate, UserParameter));
//get a new IQueryable for our new expression
Results = Results.Provider.CreateQuery<User>(WhereExpression);
//enumerate results as usual
foreach (User u in Results)
{
Console.WriteLine("{0} {1}", u.FirstName, u.LastName);
}
Working with expression trees通常可以通过使用访问者模式进行简化,但我省略了这一点,因此您可以更清楚地看到必须完成的工作。
答案 2 :(得分:0)
这是一个建议。
我没有尝试过编译和运行它,LinqToSQL充满惊喜,所以没有保证: - )
var ResultsFromProfiles = from AllPeeps in SearchDC.aspnet_Users select AllPeeps;
IEnumerable<AspNet_User> total = new AspNew_User[0];
if (SearchFirstNameBox.Checked)
{
total = total.Concat(ResultsFromProfiles.Where(p => p.tblUserProfile.FirstName.Contains(SearchTerm));}
}
if (SearchLastNameBox.Checked)
{
total = total.Concat(ResultsFromProfiles.Where(p => p.tblUserProfile.LastName.Contains(SearchTerm));
}
total = total.Distinct();