Linq查询以将某人在一段时间内的付款收据分组 [英] Linq query to group payment receipts for a person over a period

查看:51
本文介绍了Linq查询以将某人在一段时间内的付款收据分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要帮助来构造一个linq查询,以显示按人员和TransactId分组的付款. MemberId和Year将通过查询字符串传递给控制器​​.

I need help to construct a linq query to display payments grouped by person and TransactId. MemberId and Year will be passed to controller by query string.

我有这些型号

Member(MemberId,MemberName)
Payment(PayId, MemberId[foreignkey],TransactId, PayDate, Amount,CategoryId[foreignkey])
Category(CategoryId, CategoryName)

希望获得如下输出:John可以进行两次或更多次不同的付款(无限制,但提取报告的时间为12个月),每笔付款都具有唯一的带有不同付款类别的transactId.

Looking at getting an output like below: John could have made two or more different payments(unlimited but reports are fetched for 12 months) each payment is given a unique transactId with different payment categories.

因此在数据库付款中如下所示:对于30/12/2016,Cat1,Cat2,Cat3将是单独的行,但是具有相同的日期,trasactId和memberId.

So in database payment as shown below: for 30/12/2016, Cat1,Cat2,Cat3 will be separate rows but with the same date, trasactId and memberId.

Name: John Brown  TrasactId: 3089ced9-b95e-4625  PayDate: 30/12/2016
Category     Amount
Cat1          12.30   
Cat2          10.30   
Cat3          20.40
Total         43.00

Name: John Brown  TrasactId: 1088dfe8-b84e-3625  PayDate:  10/11/2016
Category     Amount
Cat1          22.30   
Cat2          20.30   
Cat3          20.40
Total         63.00

我的尝试显示了所有15种以上的付款类别,0种金额显示了未付款的类别. 例如

My attempt shows all the 15+ payment categories and 0 amount showing at categories where no payments were made. eg

Name: John Brown  TrasactId: 1088dfe8-b84e-3625  PayDate:  10/11/2016
    Category     Amount
    Cat1          22.30   
    Cat2          20.30   
    Cat3          20.40
    Cat4           0
    Cat5           0
    Cat6           0
    Cat7           0
    ....           ..
    Cat15          0
    Total         63.00

我需要什么:我只想显示付款的类别

What I need: I want to show only categories where payments were made to

public class MemberPaymentVM // for the table rows
{
    public MemberPaymentVM(int categoryCount)
    {
        Amounts = new List<decimal>(new decimal[categoryCount]);
    }
    public string Name { get; set; }
    public List<decimal> Amounts { get; set; }
    public decimal Total { get; set; }
    public string TransactId { get; set; }
    public DateTime PayDate  { get; set; }
}
public class MonthPaymentsVM
{
    [DisplayFormat(DataFormatString = "{0:MMMM yyyy}"]
    public DateTime Date { get; set; }
    public IEnumerable<string> Categories { get; set; }
    public List<MemberPaymentVM> Payments { get; set; }
}

public ActionResult YearReceipt(int year, int MemberId)
        {
            DateTime startdate = DateTime.Now;
            DateTime enddate = DateTime.Now;    
            DateTime date = DateTime.Now;
            if (year > 0 && MemberId>0)
            {
               startdate = (new DateTime(year - 1, 4, 1));
               enddate = (new DateTime(year, 3, 31));

               // date = (new DateTime(year, month, 1));
            }

            var filtered = db.Payments.ToList().Where(x => x.PayDate >= startdate && x.PayDate <= enddate && x.POK && x.MemberId==MemberId);

            var grouped = filtered.GroupBy(x => new { member = x.MemberId, category= x.Category.ID, txn = x.TransactId, pd = x.PayDate }).Select(x => new
            {
                Member = x.First().Member,
                Category = x.First().Category,
                Txn = x.First().TransactId,
                Pd = x.First().PayDate,
                Amount = x.Sum(y => y.Amount)
            });


            var data = grouped.GroupBy(x => x.Transact);
            var categories = db.Categories;
            var categoryCount = categories.Count();
            var categoryIDs = categories.Select(x => x.CategoryId).ToList();

            var model = new MonthPaymentsVM()
            {
                Date = date,
                Categories = categories.Select(x => x.CategoryName),
                Payments = new List<MemberPaymentVM>()
            };

            foreach (var group in data)
            {
                MemberPaymentVM payment = new MemberPaymentVM(categoryCount);
                var member = group.First().Member;
                var txind = group.First().Txn;
                var pd = group.First().Pd;
                payment.Name = member.Name;
                payment.TransactId = txind;
                payment.PayDate = pd;


                foreach (var item in group)
                {
                    int index = categoryIDs.IndexOf(item.Category.CategoryId);

                    payment.Amounts[index] = item.Amount;
                    payment.Total += item.Amount;
                }
                model.Payments.Add(payment);
            }



            return View(model);
        }

查看

@model Paymaster.ViewModel.MonthPaymentsVM
@foreach (var item in Model.Payments)
{

<span> Name:@item.Name 
 Pay Date: @item.PDate.ToString("dd/MM/yyyy")
 TransactId: @item.TxnId </span>


<span class="left2col">Donation Category</span> <span class="right2col">Amount</span>
<span class="left2col">                                                              
@foreach (var category in Model.Categories)
{
@category       
}                                                         
</span>                                                                 
<span class="right2col">@foreach (var amount in item.Amounts)
{
@amount
}
</span>                                                            
<span class="left2col">Total:</span> <span class="right2col"> @item.Total.ToString("c")</span>


}

推荐答案

基于您要显示的视图,您的模型不正确,需要将其设为

Based on the view you want to display, your models are incorrect and they need to be

public class MemberPaymentVM
{
    public string MemberName{ get; set; }
    public string TransactId { get; set; }
    [DisplayFormat(DataFormatString = "{0:d}")]
    public DateTime PayDate { get; set; }
    public IEnumerable<CategoryAmountsVM> Payments { get; set; }
    [DisplayFormat(DataFormatString = "{0:C}")]
    public decimal TotalAmount { get; set; }
}
public class CategoryAmountsVM
{
    public string Category { get; set; }
    [DisplayFormat(DataFormatString = "{0:C}")]
    public decimal Amount { get; set; }
}

然后,您需要从分组中删除Category,因为您要显示成员",交易"和日期"定义的分组的每个类别.

Then you need to remove the Category from the grouping since you want to display each category for the group defined by Member, Transaction and Date.

控制器方法中用于生成模型的代码必须是

The code in your controller method to generate the model needs to be

// Use .ToList() at the end so you do not load all records into memory
var filtered = db.Payments.Where(x => x.PayDate >= startdate && x.PayDate <= enddate && x.POK && x.MemberId==MemberId).ToList();

var model = filtered.GroupBy(x => new { member = x.MemberId, txn = x.TransactId, pd = x.PayDate })
    .Select(x => new MemberPaymentVM()
    {
        MemberName = x.First().Member.MemberName,
        TransactId = x.Key.txn,
        PayDate = x.Key.pd,
        TotalAmount = x.Sum(y => y.Amount),
        Payments = x.Select(y => new CategoryAmountsVM()
        {
            CategoryId = y.Category.CategoryName,
            Amount = y.Amount
        })
    });
return View(model);

然后您认为

@foreach(var item in Model)
{
    <div>
        <span>@item.MemberName</span>
        <span>@item.TransactId</span>
        <span>@Html.DisplayFor(m => item.PayDate)</span>
    </div>
    foreach(var payment in item.Payments)
    {
        <div>
            <span>@payment.Category</span>
            <span>@Html.DisplayFor(m => payment.Amount)</span>
        </div>
    }
    <div>
        <span>Total</span>
        <span>@Html.DisplayFor(m => item.TotalAmount)</span>
    <div>
}

这篇关于Linq查询以将某人在一段时间内的付款收据分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆