【问题标题】:LINQ to SQL query help (string contains any string in string array)LINQ to SQL 查询帮助(字符串包含字符串数组中的任何字符串)
【发布时间】:2010-09-07 10:37:15
【问题描述】:

我一直用这个把头发扯下来。我有一组搜索词,我正在尝试执行 LINQ to SQL 查询来针对数组中的每个项目搜索字段值。

我已经走到这一步了..

var searchResults = 
    from x in SDC.Staff_Persons
    where staffTermArray.Any(pinq => x.Forename.Contains(pinq))
        || staffTermArray.Any(pinq => x.Surname.Contains(pinq))
        || staffTermArray.Any(pinq => x.Known_as.Contains(pinq))
    orderby x.Surname
    select x;

...但后来得到了

本地序列不能在 LINQ 中使用 to SQL 实现查询 除 Contains() 外的运算符 运营商

...现在我被卡住了。

如果有人能提供帮助,我将不胜感激。 提前致谢。

罗伯

【问题讨论】:

    标签: c# linq-to-sql lambda


    【解决方案1】:

    我不确定这是否是最简单的解决方案,但这会奏效:

    var filter = CreateFilter(staffTermArray);
    
    var searchResults = 
        from person in SDC.Staff_Persons.Where(filter)
        orderby person.Surname
        select person;
    
    
    
    private static Expression<Func<Staff_Person, bool>> CreateFilter(
        string[] staffTermArray)
    {
        var predicate = PredicateBuilder.False<Staff_Person>();
    
        foreach (var staffTerm in staffTermArray)
        {
           // We need to make a local copy because of C# weirdness.
           var ping = staffTerm;
    
           predicate = predicate.Or(p => p.Forename.Contains(ping));
           predicate = predicate.Or(p => p.Surname.Contains(ping));
           predicate = predicate.Or(p => p.Known_as.Contains(ping));
        }
    
        return predicate;
    }
    

    您需要PredicateBuilder 才能正常工作。

    【讨论】:

    • 哇——我在寻找解决方案时遇到了“谓词构建器”这个词,但没有人用如此简单的术语来解释它!非常感谢!!
    【解决方案2】:

    一种选择是在客户端而不是 SQL 中进行过滤。您可以通过调用AsEnumerable() 来强制在客户端上评估where。但是,这意味着表的每一行在进行匹配测试之前都会加载到内存中,因此如果您的搜索仅匹配大表中的少量结果,它的效率可能会低得令人无法接受。

    var allPersons = 
        from x in SDC.Staff_Persons
        orderby x.Surname
        select x;
    
    var searchResults = 
        from x in allPersons.AsEnumerable()
        where staffTermArray.Any(pinq => x.Forename.Contains(pinq))
            || staffTermArray.Any(pinq => x.Surname.Contains(pinq))
            || staffTermArray.Any(pinq => x.Known_as.Contains(pinq))
        select x;
    

    【讨论】:

    • 是的,我确实有这个想法,实际上它只有 1200 条记录,所以不会太糟糕。但是我的加载时强迫症正在阻止我...... :)
    • 问题可能是这在小型测试数据库上效果很好,但是一旦客户端获得更大的数据,它就会失败。我遇到了一个案例,我们正在查看一个包含 480 万行的日志表并将其全部加载,然后无法进行过滤。
    猜你喜欢
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    • 2021-12-11
    • 1970-01-01
    • 1970-01-01
    • 2020-12-01
    相关资源
    最近更新 更多