Linq Where 子句 'AND' 'OR'

Linq Where Clause 'AND' 'OR'

如果我有这段代码,我只想知道如何使用 Linq。

private IQueryable<viewTable> BaseQuery(Models.TestDataContext db)
{
   IQueryable<viewTable> query = db.viewTables;

   foreach (string row in gridCompany.GridView.GetSelectedFieldValues("CompanyCode"))
        query = query.Where(t => t.Comp_Code == row.ToString());

   return query;
}

这段代码return查询

SELECT [t0].[Column]
FROM [dbo].[viewTable] AS [t0]
WHERE ([t0].[CompanyCode] = 'ALPHA') **AND** ([t0].[CompanyCode] = 'BETA')
ORDER BY [t0].[EditDate] DESC

如何实现查询结果到

SELECT [t0].[Column]
FROM [dbo].[viewTable] AS [t0]
WHERE ([t0].[CompanyCode] = 'ALPHA') **OR** ([t0].[CompanyCode] = 'BETA')
ORDER BY [t0].[EditDate] DESC

提前致谢。

如果我正确理解了您的要求,那么您想使用 IN clause 而不是 OR 运算符

SELECT [t0].[Column]
FROM [dbo].[viewTable] AS [t0]
WHERE ([t0].[CompanyCode] IN ('ALPHA','BETA')
ORDER BY [t0].[EditDate] DESC

这可以通过以下 Linq2Entities 查询来实现:
(我假设您使用的是 ASPxGridView。)

private IQueryable<viewTable> BaseQuery(Models.TestDataContext db)
{
    var companyCodes = gridCompany.GridView.GetSelectedFieldValues("CompanyCode")
        .Select(row => row.ToString())
        .ToList();

    return db.viewTables.Where(t => companyCodes.Contains(t.Comp_Code));
}

使用 LINQKit 您可以创建扩展方法,用于对作为 LINQ to databases 过滤器的集合进行一般测试:

public static class LinqKitExt { // using LINQKit
#region Predicates
    // searchTerms - IEnumerable<TSearch> where one must match for a row
    // testFne(row,searchTerm) - test one of searchTerms against a row
    // r => searchTerms.All(s => testFne(r,s))
    public static Expression<Func<T, bool>> AnyIs<T, TSearch>(this IEnumerable<TSearch> searchTerms, Expression<Func<T, TSearch, bool>> testFne) {
        var pred = PredicateBuilder.New<T>();
        foreach (var s in searchTerms)
            pred = pred.Or(r => testFne.Invoke(r, s));

        return (Expression<Func<T, bool>>)pred.Expand();
    }
#endregion

#region Filters
#region row matches any of searchTerms
    // searchTerms - IEnumerable<TSearch> where one must match for a row
    // testFne(row,searchTerm) - test one of searchTerms against a row
    // dbq.Where(r => searchTerms.Any(s => testFne(r,s)))
    public static IQueryable<T> WhereAny<T,TSearch>(this IQueryable<T> dbq, IEnumerable<TSearch> searchTerms, Expression<Func<T, TSearch, bool>> testFne) =>
        dbq.Where(searchTerms.AnyIs(testFne));
    public static IQueryable<T> WhereAny<T,TSearch>(this IQueryable<T> dbq, Expression<Func<T, TSearch, bool>> testFne, IEnumerable<TSearch> searchTerms) =>
        dbq.Where(searchTerms.AnyIs(testFne));
    public static IQueryable<T> WhereAny<T,TSearch>(this IQueryable<T> dbq, Expression<Func<T, TSearch, bool>> testFne, params TSearch[] searchTerms) =>
        dbq.Where(searchTerms.AnyIs(testFne));
#endregion
#endregion
}

当然AllAre/SplitContains/WhereAll/WhereSplitContains等也有自然对应的方法

有了这些可用的扩展,您的查询就变成了:

IQueryable<viewTable> query = db.viewTables.WhereAny(gridCompany.GridView.GetSelectedFieldValues("CompanyCode"), (v,s) => v == s);

注意:对于 Contains 有效的情况,这可能是更好的选择。