2017-07-07 16 views
1

私はクライアントの第三者サービスで、製品やサービスのリストを提供しています。これはちょっと混乱しています。C#Linq GroupByとSelect performance

例えば、productしかしproductrepeats itselfためservicesのすべてが返されるリスト:

製品サービスを有しともサービスBを有する製品私はリストを受け取ったときに2つの製品AサービスAとB

私がする必要があるのは、すべての製品をグループ化してそのサービスのすべてを1つにすることです。私はそれを行っていますが、私のソリューションは「ベスト」ではないと思うのでパフォーマンスが心配です。

var productsNormalized = products.Data.AsEnumerable().Select(x => new ProdutoSSO 
{ 
    CodigoServico = int.Parse(string.IsNullOrEmpty(x["CodigoServico"].ToString()) ? "0" : x["CodigoServico"].ToString()), 
    CodigoPeca = int.Parse(string.IsNullOrEmpty(x["CodigoPeca"].ToString()) ? "0" : x["CodigoPeca"].ToString()), 
    CodigoFamilia = int.Parse(string.IsNullOrEmpty(x["CodigoFamilia"].ToString()) ? "0" : x["CodigoFamilia"].ToString()), 
    Familia = x["Familia"].ToString(), 
    Servico = x["Servico"].ToString(), 
    Peca = x["Peca"].ToString(), 
    Hash = x["Hash"].ToString(), 
    Valor = decimal.Parse(string.IsNullOrEmpty(x["Valor"].ToString()) ? "0" : x["Valor"].ToString()) 
}) 
.GroupBy(x => new { x.CodigoPeca, x.CodigoFamilia, x.Familia, x.Peca }) 
.Select(x => new ProdutoGroup 
{ 
    Produto = new Produto 
    { 
     CodigoPeca = x.Key.CodigoPeca, 
     CodigoFamilia = x.Key.CodigoFamilia, 
     Familia = x.Key.Familia, 
     Peca = x.Key.Peca 
    }, 
    Servicos = x.Select(y => new ProdutoServico 
    { 
     CodigoServico = y.CodigoServico, 
     Hash = y.Hash, 
     Servico = y.Servico, 
     Valor = y.Valor 
    }).ToList() 
}); 

これを達成するためのよりよい方法がありますか、それともそれが得られるほど良いですか? ProductoComparerがある

var productsNormalized = productoSSOs 
    .Aggregate(new Dictionary<Produto,List<ProdutoServico>>(ProductoComparer), 
    (p,c) => { 
    var product = new Produto 
    { 
     CodigoPeca = c.CodigoPeca, 
     CodigoFamilia = c.CodigoFamilia, 
     Familia = c.Familia, 
     Peca = c.Peca 
    }; 
    var service = new ProdutoServico 
    { 
     CodigoServico = c.CodigoServico, 
     Hash = c.Hash, 
     Servico = c.Servico, 
     Valor = c.Valor 
    }; 
    if (!p.ContainsKey(product)) 
    { 
     p[product] = new List<ProductoServico>() { service }; 
    } 
    else 
    { 
     p[product].Add(service); 
    } 
    return p; 
}); 

IEqualityComparer<Producto>(あるいはあなたがEqualsを実装することができます:あなたはこのような何かを行うことができ集計を使用して

+4

コード取得にはどのくらいの時間がかかりますか?あなたはどれくらいそれを取るべきですか? – mjwills

+1

* 'すべてのサービスを1つだけ取得する' * - あなたはすべてのグループとすべてのサービスを利用しているようです。フィルタリングはなく、 'Take(1)'や 'First()'のようなものはありません。 –

+0

@SergeyBerezovskiy問題はサービスです。それはすべての製品のリストを返します。私は私の側でこれをしなければならない – Terkhos

答えて

2

(あなたが完全に必要ではないかもしれませんProdutoSSOのリスト、と始めていると仮定した場合) GetHashCodeProductoに入れるか、キーを生成するだけで他の方法でキーを生成することもできます。たとえば、フィールドを連結するなど)。

私は元のクラスやデータを持っていないので、これは明らかにテストされていません。

これは、あなたが必要とするかもしれないDictionary<Producto, List<ProductoServico>>を与えます。または、必要ならば簡単にIEnumerable<ProdutoGroup>に変換できます。

+0

「メソッドEnumerable.Aggregate (IEnumerable 、TAccumulate、Func )の型引数は、この使用法から推測できません。明示的に型引数を指定してみてください。 ' – Terkhos

+0

申し訳ありません、私は*集計を使うときはいつも' return'を忘れています。やってみよう。 –

+0

私は既に返品pを追加していました。それでも私には同じメッセージが表示されます。タイプを定義できないようです。 'Aggregate <>'に追加しようとしましたが、正しい一致が見つかりませんでした。 – Terkhos