使用lambda表达式的GroupBy和Count

时间:2016-06-27 19:46:52

标签: c# linq

我想根据国籍,城市,类型,代码和付款计划创建发票总结,其中包含用户数量和发票总额

我有以下课程:

public class Nationality
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class UserType
{
    public int Id { get; set; }
    public int TypeName { get; set; }
}

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
    public Nationality Nationality { get; set; }
    public UserType UserType { get; set; }
}

public class Invoice
{
    public int Id { get; set; }
    public double Total { get; set; }
    public string City { get; set; }
    public string PaymentPlan { get; set; }
    public int UserId { get; set; }
    public User User { get; set; }
}

public class InvoiceSummery
{
    public int UserCount { get; set; }
    public double GrandTotal { get; set; }
    public string NationalityName { get; set; }
    public string PaymentPlan { get; set; }
    public string TypeName { get; set; }
    public string City { get; set; }
    public string Code { get; set; }
}

发票示例:

enter image description here

发票摘要结果应为:

enter image description here

这是我试过的:

private IEnumerable<InvoiceSummery> CreateSummery(IEnumerable<Invoice> invoices)
    {
        return invoices.GroupBy(x => new { x.User.Id, x.User.Nationality.Name, x.User.UserType.TypeName, x.User.Code, x.City,x.PaymentPlan })
            .Select(g => new InvoiceSummery
            {
                UserCount = g.Count(),

                GrandTotal = g.Sum(s => s.Total),
                NationalityName = g., // here assigne the rest Nationality name, city ... etc ??

            });
    }

但它没有用,没有完成分组。 我也不知道如何分配国籍和城市等计算字段。

由于

2 个答案:

答案 0 :(得分:1)

您可以使用Key.fieldname访问分组中使用的元素。

private IEnumerable<InvoiceSummery> CreateSummery(IEnumerable<Invoice> invoices)
{
    // Removed 'UserId`  
    return invoices.GroupBy(x => new { x.User.Nationality.Name, x.User.UserType.TypeName, x.User.Code, x.City,x.PaymentPlan })
        .Select(g => new InvoiceSummery
        {
            Nationality = g.Key.Name,
            TypeName = g.Key.TypeName,
            Code = g.Key.Code,
            PaymentPlan = g.Key.PaymentPlan ,
            City = g.Key.City,
            UserCount = g.Count(),
            GrandTotal = g.Sum(s => s.Total)
        });
}

答案 1 :(得分:0)

试试这个

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Nationality", typeof(string));
            dt.Columns.Add("User Name", typeof(string));
            dt.Columns.Add("User Type", typeof(string));
            dt.Columns.Add("Code", typeof(string));
            dt.Columns.Add("Total", typeof(decimal));
            dt.Columns.Add("City", typeof(string));
            dt.Columns.Add("Plan", typeof(string));

            dt.Rows.Add(new object[] { "BE", "Mike", "VIP", "A B", 2.000, "Brussels", "Monthly"});
            dt.Rows.Add(new object[] { "BE", "David", "VIP", "A B", 2.000, "Brussels", "Monthly" }); 
            dt.Rows.Add(new object[] { "BE", "Jill", "VIP", "A B C", 2.000, "Brussels", "Monthly" }); 
            dt.Rows.Add(new object[] { "BE", "Kim", "ST", "A B C", 2.000, "Antwerpen", "Monthly" });
            dt.Rows.Add(new object[] { "BE", "Sabrina", "ST", "A B C", 2.000, "Antwerpen", "Monthly" });

            DataTable dt2 = new DataTable();
            dt2.Columns.Add("Nationality", typeof(string));
            dt2.Columns.Add("UserCount", typeof(int));
            dt2.Columns.Add("TypeName", typeof(string));
            dt2.Columns.Add("Code", typeof(string));
            dt2.Columns.Add("GrandTotal", typeof(decimal));
            dt2.Columns.Add("City", typeof(string));
            dt2.Columns.Add("PaymentPlan", typeof(string));

            var groups = dt.AsEnumerable().GroupBy(x => new  {_type = x.Field<string>("User Type"), code = x.Field<string>("Code")});

            foreach (var group in groups)
            {
                dt2.Rows.Add(new object[] {
                    group.FirstOrDefault().Field<string>("Nationality"),
                    group.Count(),
                    group.FirstOrDefault().Field<string>("User Type"),
                    group.FirstOrDefault().Field<string>("Code"),
                    group.Select(x => x.Field<decimal>("Total")).Sum(),
                    group.FirstOrDefault().Field<string>("City"),
                    group.FirstOrDefault().Field<string>("Plan")
                });

            }
        }
    }
}