简体   繁体   English

C#Linq GroupBy和Select性能

[英]C# Linq GroupBy and Select performance

I'm working with a third part service of my client that is providing me a list of products and services, which is a little bit of a mess. 我正在与客户的第三方服务一起工作,该服务向我提供了产品和服务的列表,这有点混乱。

The list will return all of the services for the product but the product repeats itself , for example: 该列表将返回该product所有services ,但该product repeats itself ,例如:

The product A has the service A and the product A also has the service B so, when i receive the list i will get two products A with services A and B 产品A具有服务A产品A也具有服务B,因此,当我收到列表时,我将获得带有服务A和B的 两个产品A

What i need to do is to group all of the products to get only one with all of it's services and i have done so but i'm worried about performance because i think my solution isn't the 'best' one: 我需要做的是将所有产品组合在一起,以仅获得所有服务的全部,而且我这样做了,但是我担心性能,因为我认为我的解决方案不是“最佳”解决方案:

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

Is there a better way to achieve this or this is as good as it gets? 有没有更好的方法来实现这一目标,或者说它已经尽善尽美了?

Using Aggregate you could do something like this (assuming you are starting with a list of ProdutoSSO , which might not be entirely necessary): 使用Aggregate,您可以执行以下操作(假设您从ProdutoSSO列表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;
});

Where ProductoComparer is an IEqualityComparer<Producto> (or alternatively you could implement Equals and GetHashCode in Producto , or you could just generate a key some other way - concatenating fields together, for example). 其中ProductoComparerIEqualityComparer<Producto> (或者您可以在Producto实现EqualsGetHashCode ,或者可以通过其他方式生成键-例如,将字段连接在一起)。

This is obviously untested since I don't have the original classes or data. 这显然未经测试,因为我没有原始的类或数据。

This would give you a Dictionary<Producto, List<ProductoServico>> which might be all you need, or you can easily transform it into an IEnumerable<ProdutoGroup> if you want. 这将为您提供一个Dictionary<Producto, List<ProductoServico>> ,它可能就是您所需要的,或者您可以根据需要轻松地将其转换为IEnumerable<ProdutoGroup>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM