什么是在linq中写连接的最快方法

时间:2017-08-04 15:55:01

标签: c# performance list linq dictionary

我有2个类用户(count-10k),地址(count-1million)。这些就像一对多。

我正在尝试为用户映射地址。

使用列表(需要几分钟):

 List<User> us = usrs.Select(u => new User { id = u.id ,email=u.email,name=u.name,addresses=adrs.Where(a=>a.userid==u.id).ToList()}).ToList();

上述工作但很慢

我将其更改为使用字典及其快速。

使用词典(需要几秒钟):

var dusrs = usrs.ToDictionary(usr => usr.id);
        var daddrs = adrs.ToDictionary(adr => Tuple.Create(adr.id,adr.userid));
        foreach (var addr in daddrs)
        {

            var usr = dusrs[addr.Value.userid];
            if (usr.addresses == null)
            {
                usr.addresses = new List<Address>();

            }
            usr.addresses.Add(addr.Value);
        }

有什么方法可以使用列表而不是字典来编写更好的查询?

我只是想看看我是否可以使用列表编写更好的linq

感谢...

vamsee

1 个答案:

答案 0 :(得分:1)

假设您出于某种原因在List中保留用户和地址,可以在LINQ中使用join,它将合并两个list并在内部使用散列数据结构将它们放在一起:

var us2 = (from u in usrs
          join a in adrs on u.id equals a.userid into aj
          select new User { id = u.id, email = u.email, name = u.name, addresses = aj.Select(a => a).ToList() }).ToList();

或者,您可以将地址转换为Lookup并使用该地址,但最好将地址保留在Lookup中或最初在Lookup中创建地址如果可能的话:

var addressLookup = adrs.ToLookup(a => a.userid);
List<User> us = usrs.Select(u => new User { id = u.id, email=u.email, name=u.name, addresses=addressLookup[u.id].ToList() }).ToList();

在我的测试用例中,速度更快似乎取决于用户与地址的匹配程度。