2011-02-04 46 views
0

我想在LINQ中翻译这个查询......如果我们在纯SQL中执行它,但是在动态创建的LINQ查询中(构建基于用户输入的搜索查询),这是非常容易的,它是一个全新的故事。在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的,尽管我不明白的方式来实现在这里吧...

+0

'WHERE 1 = 1`的用途是什么?这不仅仅意味着“真实”,并且不会有所作为? – Marcus 2011-02-04 14:49:20

+6

@G_M - 通常这是在构建动态SQL时完成的,因此您不需要继续检查现有的where子句。 – Oded 2011-02-04 14:50:17

+0

是你的问题如何动态地处理OR? – JohnOpincar 2011-02-04 15:28:21

回答

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

希望能帮助

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()的。在我看来,阅读起来更容易。因人而异。

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意味着相同,但大小写敏感

1

为了得到Like ..或者Like ..等等,我认为你必须编写自己的扩展来为你构建表达式树。我想做到这一点前一阵子,结束了在计算器上这里找到一个不同的文章:Linq to Sql any keyword search query

从那里,我想你会这样写:

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

顺便说一句,你还可以在更改代码链接页面做的,而不是或改变

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

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

这是我当时想要的,叫它LikeAll