C#Linq GroupBy和Select performance

时间:2017-07-07 14:24:27

标签: c# linq

我正在使用我的客户的第三方服务,它为我提供了一系列产品和服务,这有点乱。

该列表将返回services的所有product,但product repeats 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()
});

有没有更好的方法来达到这个目标,或者这样做是否合适?

1 个答案:

答案 0 :(得分:2)

使用Aggregate你可以做这样的事情(假设你从一个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>(或者您可以在Equals中实施GetHashCodeProducto,或者您可以通过其他方式生成密钥 - 例如,将字段连接在一起。)

这显然是未经测试的,因为我没有原始的类或数据。

这会为您提供Dictionary<Producto, List<ProductoServico>>,这可能就是您所需要的,或者您可以根据需要轻松将其转换为IEnumerable<ProdutoGroup>