简体   繁体   English

Linq-to-SQL:忽略WHERE子句中的空参数

[英]Linq-to-SQL: Ignore null parameters from WHERE clause

The query below should return records that either have a matching Id supplied in ownerGroupIds or that match ownerUserId . 下面的查询应该返回在ownerGroupIds中提供匹配ID或匹配ownerUserId的记录 However is ownerUserId is null, I want this part of the query to be ignored. 但是ownerUserId为null,我希望忽略查询的这一部分。

    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();
    }

However when a null is passed in for ownerUserId then I get the following error: Nullable object must have a value. 但是,当为ownerUserId传入null时,我收到以下错误: Nullable object must have a value.

I get a tingling I may have to use a lambda expression in this instance? 在这种情况下,我可能不得不使用lambda表达式?

your issue is that your are not passing in a nullable int, you are passing in a null. 你的问题是你没有传入一个可以为空的int,你传递的是null。

try this: 试试这个:

Print(null);

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

and you get the same error. 你得到同样的错误。

It should work if you do this: 它应该工作如果你这样做:

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();

Have you some contacts with OwnerUserId null? 你和OwnerUserId有一些联系吗? If yes, c.OwnerUserId could be null and not having any value in c.OwnerUserId.Value 如果是,则c.OwnerUserId可以为null,并且在c.OwnerUserId.Value没有任何值

What about conditionally adding the where clause to the expression tree? 有条件地将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();
    }

PROBLEM: "&&" and "||" 问题:“&&”和“||” is converted to a method like "AndCondition(a, b)", so "!a.HasValue || a.Value == b" becomes "OrCondition(!a.HasValue, a.Value == b);" 被转换为像“AndCondition(a,b)”这样的方法,所以“!a.HasValue || a.Value == b”变为“OrCondition(!a.HasValue,a.Value == b);” The reason for this is probably to get a generic solution to work for both code and SQL statements. 这样做的原因可能是获得适用于代码和SQL语句的通用解决方案。 So instead, use the "?:" notation. 因此,请使用“?:”表示法。

For more, see my blog post: http://peetbrits.wordpress.com/2008/10/18/linq-breaking-your-logic/ 有关更多信息,请参阅我的博客文章: 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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM