繁体   English   中英

Linq在多个表之间有区别吗?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM