2011-01-10 66 views
1

下面的linq resuired对我的大脑来说太过于沉闷,我甚至试图做甚么可能?Linq跨多个表区分?

var aa = new string[] { "1", "2" }; 
var bb = new string[] { "1", "2", "3" }; 
var cc = new string[] { "2" }; 

//*cannot directly reference the above anymore*// 
var dd = new string[][] { aa, bb, cc }; 
//result = dd.**magical linq to only get item(s) present in each table** i.e. result = {"2"} 
+0

我真的笑了,当我读`魔法linq`。 – Kredns 2011-01-10 09:54:31

回答

3
var result = dd.Aggregate<IEnumerable<string>>((a, x) => a.Intersect(x)); 

如果你稍微想更好的理论性能,那么您可以改为执行以下操作。它避免了为每个相交操作构造一个新集合的需要,使用明确的HashSet<T>将结果传递给下一个迭代而不是普通的IEnumerable<T>

var result = dd.Aggregate((HashSet<string>)null, 
          (a, x) => { 
             if (a == null) 
              a = new HashSet<string>(x); 
             else 
              a.IntersectWith(x); 
             return a; 
            }); 
3

可能有niftier方式,但你可以建立在一个循环的查询:在一些可读性为代价

var aa = new string[] { "1", "2" }; 
var bb = new string[] { "1", "2", "3" }; 
var cc = new string[] { "2" }; 

var dd=new string[][] { aa, bb, cc }; 

IEnumerable<string> q=dd.First(); 

for(var i=1;i<dd.Length;++i) 
{ 
    q=q.Intersect(dd[i]); 
} 
+0

Linq的整点是为了避免循环? – RichardW1001 2011-01-10 10:15:43

+0

@Richard:LINQ的重点不在于避免循环;这是为了让代码更具表现力和可读性。通常情况下,一个简单的循环比它的LINQ等价物更具可读性。 – LukeH 2011-01-10 10:18:58

3

你可以使用一套运营商 - 联合,相交等

(编辑 - 误读的问题!)

相信相交为您提供后开箱的是什么:

var dd = aa.Intersect(bb).Intersect(cc); 

请注意,这将工作,因为aa bb和cc已经是所有相同类型的IEnumerables。如果您IEnumerables是不同类型的(比如从不同的LINQ表)你必须对项目所需的属性:

var dd = aa.Select(a => a.PropertyA).Intersect(bb.Select(b => b.PropertyB).Intersect(cc.Select(c => c.PropertyC); 

结果会有一个IQueryable,所以你可以在ToArray的(),ToList链()等结尾给你想要的结果。

0

为什么不使用简单的连接?

class Program 
{ 
    static void Main(string[] args) 
    { 
     var aa = new string[] { "1", "2", "4" }; 
     var bb = new string[] { "1", "2", "3", "4" }; 
     var cc = new string[] { "2", "4" }; 

     //*cannot directly reference the above anymore*// 
     var dd = new string[][] { aa, bb, cc }; 

     var result = dd.Aggregate((x, y) => x.Join(y, z => z, z => z, (z, v) => z).ToArray()); 
     foreach (var item in result) 
     { 
      Console.WriteLine(item); 
     } 
     Console.ReadLine(); 
    } 
} 
3

注意,如果你正在使用LINQ to SQL和你施放的复合查询的任何部分的IEnumerable <>,这部分无法与其他部分的查询,以形成一个单一的SQL查询相结合。在示例中,使用SQL作为数据源时会发生这种情况,其中查询被隐式转换为IEnumerable <>,当它被分配给'q'时。改用IQueryable。尽管每个IEnumerable都被延迟,但三个SQL查询将被发送到服务器,并且交叉点将在内存中执行。

请参阅Returning IEnumerable<T> vs. IQueryable<T>或搜索“IEnumerable vs IQueryable”以获取引用。