Linq-to-SQL: игнорировать нулевые параметры из предложения WHERE - PullRequest
3 голосов
/ 26 марта 2010

В приведенном ниже запросе должны быть возвращены записи, которые либо имеют соответствующий Id, указанный в ownerGroupIds , либо совпадают с ownerUserId . Однако ownerUserId равно нулю, я хочу, чтобы эта часть запроса была проигнорирована.

    public static int NumberUnderReview(int? ownerUserId, List<int> ownerGroupIds)
    {
        return ( from c in db.Contacts
                 where 
                 c.Active == true 
                 &&
                 c.LastReviewedOn <= DateTime.Now.AddDays(-365) 
                 &&
                 ( // Owned by user
                    !ownerUserId.HasValue || 
                    c.OwnerUserId.Value == ownerUserId.Value
                 )
                 &&
                 ( // Owned by group
                    ownerGroupIds.Count == 0 ||
                    ownerGroupIds.Contains( c.OwnerGroupId.Value )
                 )
                 select c ).Count();
    }

Однако, когда для ownerUserId передается значение NULL, я получаю следующую ошибку: Nullable object must have a value.

Я чувствую покалывание. Возможно, мне придется использовать лямбда-выражение в этом случае?

Ответы [ 4 ]

3 голосов
/ 26 марта 2010

Ваша проблема в том, что вы не передаете пустое int, вы передаете нулевое значение.

попробуйте это:

Print(null);

private void Print(int? num)
{
     Console.WriteLine(num.Value);
}

и вы получите ту же ошибку.

Это должно работать, если вы сделаете это:

var q = ( from c in db.Contacts
                 where 
                 c.Active == true 
                 &&
                 c.LastReviewedOn <= DateTime.Now.AddDays(-365) 
                 &&
                 ( // Owned by group
                    ownerGroupIds.Count == 0 ||
                    ownerGroupIds.Contains( c.OwnerGroupId.Value )
                 )
                 select c );

if(ownerUserId != null && ownerUserId.HasValue)
     q = q.Where(p => p.OwnerUserId.Value == ownerUserId.Value);

return q.Count();
2 голосов
/ 26 марта 2010

Есть ли у вас контакты с OwnerUserId null? Если да, c.OwnerUserId может быть нулевым и не иметь значения в c.OwnerUserId.Value

0 голосов
/ 21 июня 2010

ПРОБЛЕМА: "&&" и "||" преобразуется в метод типа «AndCondition (a, b)», поэтому «! a.HasValue || a.Value == b» становится «OrCondition (! a.HasValue, a.Value == b);» Причина этого, вероятно, заключается в том, чтобы получить общее решение для работы как с кодом, так и с операторами SQL. Поэтому вместо этого используйте нотацию "?:".

Подробнее см. В моем блоге: http://peetbrits.wordpress.com/2008/10/18/linq-breaking-your-logic/

// New revised code.
public static int NumberUnderReview(int? ownerUserId, List<int> ownerGroupIds)
{
    return ( from c in db.Contacts
             where 
             c.Active == true 
             &&
             c.LastReviewedOn <= DateTime.Now.AddDays(-365) 
             &&
             ( // Owned by user
                // !ownerUserId.HasValue || 
                // c.OwnerUserId.Value == ownerUserId.Value
                ownerUserId.HasValue ? c.OwnerUserId.Value == ownerUserId.Value : true
             )
             &&
             ( // Owned by group
                // ownerGroupIds.Count == 0 ||
                // ownerGroupIds.Contains( c.OwnerGroupId.Value )
                ownerGroupIds.Count != 0 ? ownerGroupIds.Contains( c.OwnerGroupId.Value ) : true
             )
             select c ).Count();
}
0 голосов
/ 26 марта 2010

А как насчет условного добавления предложения where в дерево выражений?

public static int NumberUnderReview(int? ownerUserId, List<int> ownerGroupIds)
    {

    var x = ( from c in db.Contacts
                 where 
                 c.Active == true 
                 &&
                 c.LastReviewedOn <= DateTime.Now.AddDays(-365) 
                 &&
                 ( // Owned by group
                    ownerGroupIds.Count == 0 ||
                    ownerGroupIds.Contains( c.OwnerGroupId.Value )
                 )
                 select c );

    if (ownerUserId.HasValue) {
        x = from a in x
            where c.OwnerUserId.Value == ownerUserId.Value
    }

    return x.Count();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...