在“linq to sql”查询中将null作为Contains()传递

时间:2013-08-01 13:12:59

标签: linq linq-to-sql

我在linq to sql查询中遇到包含问题,如下所示:

 public IAuditRecord[] Fetch(SearchConditions searchConditions)
    {
        IAuditRecord[] searchedList = (from rows in _dbContex.AuditTrails
                                         where 
                                         (searchConditions.Owner == null || searchConditions.Owner == 0) ? true : rows.Owner == searchConditions.Owner
                                         &&
                                         /*This line cannot compile when ActionIDs array is empty*/
                                         (searchConditions.ActionIDs != null && searchConditions.ActionIDs.Length != 0) ? searchConditions.ActionIDs.Contains(rows.UserActionID) : true
                                         && ((searchConditions.StartDate != null && searchConditions.EndDate != null) ?  (rows.TimeStamp >= searchConditions.StartDate && rows.TimeStamp <= searchConditions.EndDate)
                                         : (searchConditions.StartDate != null && searchConditions.EndDate == null) ?  rows.TimeStamp >= searchConditions.StartDate : (searchConditions.StartDate == null && searchConditions.EndDate != null) ?  (rows.TimeStamp <= searchConditions.EndDate)
                                         : true)
                                       select rows).ToArray();
        return searchedList;
    }

如果searchCondition.ActionIDs数组不为null或为空,则此查询执行完美, 但当我将ActionIDs数组作为null传递时,无法编译查询。

所以主要问题是当ActionIDs数组为null时,为什么包含不起作用?

1 个答案:

答案 0 :(得分:0)

您正在构建一个IQueryable,它定义 如何查询某些内容,而不是实际执行此操作。为此,它构建了一个Expression,它定义了所有查询意图,稍后可以调用它来实际获取数据。如果你使用的是LINQ-to-Objects,这可能会有效,因为它可能先调用searchConditions.ActionIDs != null,然后知道它不必尝试执行第二部分。 Linq-to-Entities / SQL等没有这种好处。

长话短说,您可以这样做:

searchConditions.ActionIDs = searchConditions.ActionIDs ?? new int[];

如果是null,则执行不同的查询,如:

var query = _dbContext.AuditTrails;

if(searchConditions.ActionIDs != null && searchCondition.ActionIDs.Length != 0)
{
    query = // Further filtered query where ActionIDs are taken into account.