代码之家  ›  专栏  ›  技术社区  ›  Earlz

使用可选搜索子句执行LINQ查询

  •  0
  • Earlz  · 技术社区  · 14 年前

    我有一个网页,你可以搜索的人。他们可以得到一个所有人的列表,也可以根据名字或姓氏等特定条件进行筛选。

    this question .

    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;
    

    我在构建查询时遇到一个空引用错误,但是当firstname和lastname都为空时。删除where子句可以消除错误。

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

    4 回复  |  直到 7 年前
        1
  •  1
  •   Joe Albahari    14 年前

    使用字符串。等于:

    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问题,还迫使您指定一个字符串比较类型(一件好事)。换句话说,在执行不区分大小写的比较时,指定是使用特定于本地区域性的规则还是使用不变区域性的规则。

        2
  •  1
  •   Omu    14 年前

    你不需要打电话 ToLower()

    string.Compare(firstName, p.FirstName, true) 
    
        3
  •  0
  •   ernie.cordell    14 年前

    在调用ToLower之前,请确保它不为null:

    (firstname==null || (firstname!= null && firstname.ToLower()==p.FirstName.ToLower()))
    
        4
  •  0
  •   Josh E    14 年前

    true ,不允许评估短路。为什么不使用等价规则来翻转语句?

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

    编辑:我写了以下内容,并在linqpad4中成功运行了它,没有任何问题。我想 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;}
    }