[英]Linq Distinct across multiple tables?
下面恢复的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"}
可能有更巧妙的方法,但是您可以循环构建查询:
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]);
}
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;
});
您可以使用集合运算符-联合,相交等。
(编辑-误读的问题!)
我相信Intersect可为您提供开箱即用后的功能:
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()等上进行链接以提供所需的结果。
警告,如果您使用LINQ to SQL,并且将组合查询的任何部分转换为IEnumerable <>,则该部分不能与查询的其余部分组合在一起以形成单个SQL查询。 在支出者的示例中,使用SQL作为数据源将发生这种情况,其中当查询被分配给'q'时,隐式将查询强制转换为IEnumerable <>。 改用IQueryable。 尽管每个IEnumerable都被推迟,但三个SQL查询将被发送到服务器,并且交集将在内存中执行。
请参阅返回IEnumerable <T>与IQueryable <T>或搜索“ IEnumerable vs IQueryable”以获取引用。
为什么不使用简单的联接?
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();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.