2017-08-04 11 views
0

私は2クラスのユーザ(count-10k)、アドレス(count-1million)を持っています。これらは1対多のものです。linqで最も速くjoinを書く方法

ユーザーの住所をマップしようとしています。リストを使用して

(数分かかります):

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

は私がリストではなく、辞書を使用して、より良いクエリを書くことができる方法はありますか?

私はちょうど私が

おかげで...

vamsee

+0

レビューのため、codereview.stackexchange.comに行く必要がありますので、この質問を締めくくっています。 – HimBromBeere

+1

['GroupJoin'](https://msdn.microsoft.com)を見てください。 /en-us/library/bb534297(v=vs.110).aspx)メソッドまたは[join into](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/join -clause) –

+0

'adrs.ToLookUp(k => k.userid)'のようなルックアップを使用して、ルックアップからユーザIDごとにアドレスリストを抽出することができます。 – ViRuSTriNiTy

答えて

1

あなたは、あなたには、いくつかの理由でList s内のユーザーとアドレスを維持していると仮定するリストを使用して、より良いLINQを書くことができるかどうかを確認しようとしていますLINQ内のjoinを使用して、2つの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(); 

より速いケースは、ユーザー対アドレスの数に依存するように見えます。

+0

あなたのものと同じなので私の答えを削除しました – tinudu

関連する問題