在LINQ中翻译此查询? (清单之类的)

时间:2011-02-04 14:46:38

标签: c# .net linq linq-to-sql

我想在LINQ中翻译这个查询...如果我们在纯SQL中进行构建很容易,但是在动态创建的LINQ查询中(根据用户输入构建搜索查询)这是一个全新的故事。

SELECT * FROM MyTable 
WHERE 1=1
  AND Column2 IN (1,2,3)
  AND ( Column1 LIKE '%a%' OR Column1 LIKE '%b%' )

现在尝试构建它,我们尝试了这种方式:

if(myOjb.Column2Collection != null)
    query = query.where(f => f.Column2.Contains(myOjb.Column2Collection));

if(myObj.Column1Collection != null)
{
    // tough part here ?
    //query = query.Where(); ...
}

那么通常情况下最好的方法是什么?

请注意,我知道SqlMethod.Like,因为我无法想办法在这里实现它...

5 个答案:

答案 0 :(得分:1)

要获得Like ..或Like ..等,我认为你必须编写自己的扩展来为你构建表达式树。我想在不久前做到这一点,最后在StackOverflow上找到另一篇文章:Linq to Sql any keyword search query

从那里开始,我想你会写下这个:

string[] terms = new string[] {"a", "b"}
query = query.LikeAny(table => table.Column1, terms)

顺便说一句,您也可以通过更改

来更改链接页面上的代码以进行AND而不是OR
var body = conditions.Aggregate((acc, c) => Expression.Or(acc, c));

var body = conditions.Aggregate((acc, c) => Expression.And(acc, c));

这是我当时想要的,称之为LikeAll

答案 1 :(得分:0)

尝试这样的事情:

var colums2 = { 1, 2, 3 };
var result = (from o in myOjb
              where columns2.Any(co2 => co2 == o.Column2)
              && Column1.Contains(column2valueA)
              || Column1.Contains(column2valueB)
              select o);

希望可以提供帮助

答案 2 :(得分:0)

var sc = StringComparison.OrdinalIgnoreCase;
var col2Values = new int[] { 1, 2, 3 };    

var query = from item in myObj
            where col2Values.Contains(item.Column2)
            && (item.Column1.IndexOf("a", sc) >= 0
                || item.Column1.IndexOf("b", sc) >= 0)
            select item;

我还没有测试过,但它构建得很好。如果上述原因失败,则为原始版本:

var col2Values = new int[] { 1, 2, 3 };

var query = from item in myObj
            let col1 = item.Column1.ToLower()
            where col2Values.Contains(item.Column2)
            && (col1.Contains("a") || col1.Contains("b"))
            select item;

我实际上更喜欢第二个版本,即使由于ToLower()稍微较慢。在我看来,它更容易阅读。 YMMV。

答案 3 :(得分:0)

from o in myObj
where
new[] { 1, 2, 3 }.Contains(o.Column2) &&
new[] { "a", "b" }.Any(s => o.Column1.IndexOf(s, StringComparison.Ordinal) != -1)
select o;

如果您关心查找性能,请使用new Hashset<T>。数组只带来O(n)。


Ordinal表示unicode比较每字节字节,没有特定于文化的问题,最快。

OrdinalIgnoreCase表示相同但区分大小写

答案 4 :(得分:0)

尝试this