2017-07-07 60 views
1

我正在爲客戶提供第三方服務,該服務向我提供產品和服務的清單,這些清單有點亂。C#Linq GroupBy和Select性能

名單將返回所有servicesproductproductrepeats itself,例如:

產品A服務A產品A也有服務B所以,當我收到名單我會得到兩個產品A服務A和B

我需要做的是將所有產品進行分組,以獲得所有產品的服務,並且我已經這樣做了,但是我擔心性能,因爲我認爲我的解決方案不是'最好的':

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

有沒有更好的方法來實現這一目標,或者這樣做還不錯?

+4

代碼需要多長時間?你想要多久? – mjwills

+1

*'只能得到一個所有的服務'* - 看起來好像你在查詢所有組和所有服務。沒有過濾,也沒有像'Take(1)'或'First()'# –

+0

@SergeyBerezovskiy問題是服務,它將返回一個所有產品的列表,沒有過濾器,沒有任何東西。我必須在我身邊這樣做 – Terkhos

回答

2

使用聚合,你可以做這樣的事情(假設你開始用ProdutoSSO名單,這可能不是完全必要的):

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

ProductoComparerIEqualityComparer<Producto>(或者你也可以實現EqualsGetHashCodeProducto中,或者您可以通過其他方式生成密鑰 - 例如將字段連接在一起)。

這顯然沒有經過測試,因爲我沒有原始的類或數據。

這會給你一個Dictionary<Producto, List<ProductoServico>>這可能是你所需要的,或者你可以很容易地將它轉換成IEnumerable<ProdutoGroup>如果你想。

+0

它給我一個錯誤:'的類型參數方法 'Enumerable.Aggregate (IEnumerable的,TAccumulate,函數功能)' 不能從使用推斷。嘗試明確指定類型參數' – Terkhos

+0

對不起,我*總是*在使用'Aggregate'時忘記'return'。現在就試試。 –

+0

我已經添加了返回p。它仍然向我顯示相同的消息,看起來它不能定義類型。我試圖在'Aggregate <>'中添加它們,但我找不到正確的匹配項。 – Terkhos