0

我有一个页面,您可以在其中搜索人。他们可以获取所有人的列表,也可以通过某些标准(例如名字或姓氏)对其进行过滤。

到目前为止,我一直在尝试使用这个问题中详述的技术。

所以我的代码看起来像

string firstname=...
string lastname=...

var people=from p in People.All()
           where (firstname==null || firstname.ToLower()==p.FirstName.ToLower()) &&
                 (lastname==null || lastname.ToLower()==p.LastName.ToLower())
           select p;

构建查询时出现空引用错误,但是当名字和姓氏都为空时。删除 where 子句可以消除错误。

为什么这行不通?C# 是否尝试评估 where 子句每个部分的第二部分?这不应该是因为短路或对吗?

4

4 回答 4

1

你不需要调用ToLower()use string.compare 来代替 ignoreCase

string.Compare(firstName, p.FirstName, true) 
于 2010-07-16T18:08:28.750 回答
1

使用字符串。等于:

from p in People.All()
where (firstname == null || string.Equals (firstname, p.FirstName, StringComparison.InvariantCultureIgnoreCase)) &&
      (lastname == null || string.Equals (lastname, p.LastName, StringComparison.InvariantCultureIgnoreCase))
select p

这不仅避免了 null 问题,而且还强制您指定字符串比较类型(一件好事)。换句话说,您指定在执行不区分大小写的比较时是使用特定于本地文化还是不变文化的规则。

于 2010-07-17T02:06:07.677 回答
0

在调用 ToLower 之前确保它不为空:

(firstname==null || (firstname!= null && firstname.ToLower()==p.FirstName.ToLower()))
于 2010-07-16T17:54:04.843 回答
0

当两者都为 null 时它不起作用,因为语句的第一部分将评估为true,不允许评估短路。为什么不使用等价规则来翻转语句?

(firstName != null && firstName.ToLower() == p.firstName.ToLower()) 

编辑:我写了以下内容并在 LINQPad 4 中成功运行,没有任何问题。我假设调用People.All()只是返回一个IQueryable<People>完整的记录集?也许在这里发布您的异常文本,以便我们查看您是否无意中错过了什么?

void Main()
{
    string a = null;
    string b = null;
    var peeps = new List<Person> { 
        new Person { 
            FirstName = "John",
            LastName = "Connor"
        },
        new Person { 
            FirstName = "Sarah",
            LastName = "Connor",
        },
        new Person { 
            FirstName = "Cletus",
            LastName = "Handy"
        }
    };

    var somePeeps = from p in peeps
        where (a == null || a.ToLower() == p.FirstName.ToLower()) 
            && (b == null || b.ToLower() == p.LastName.ToLower())
        select p;

    somePeeps.Dump();

}

public class Person
{
    public string FirstName { get; set;}
    public string LastName { get; set;}
}
于 2010-07-16T17:57:31.260 回答