繁体   English   中英

如何在 linq 中获取上个月和下个月的记录

[英]How to get previous and next months records in linq

我正在使用 EF core 6,我需要使用 LINQ 获取上个月和下个月的记录。 有一个带有月份名称的下拉列表,我会将所选月份的月份编号发送到 LINQ 条件

如果我 select 1 月,它应该从上年和当年 2 月全月记录中得到 12 月全月记录的结果。

当我使用以下谓词时,它没有提供正确的结果

 Func<Products, bool>? predicate = i => i.CreatedDate.Month > month + 1 && i.CreatedDate.Month < month - 1;

Product
ID Name CreatedDate   Amount
1  John 21/12/2021    1000   
2  Mark 10/12/2021    2000  
3  Steve 02/01/2022   3000 
4  Arun 21/01/2022    4000 
5  Adi 10/02/2022     5000
6  Sanjay 11/02/2022  6000 
7  Sanjay 14/02/2022  7000 

我还需要根据所选月份获取每个月的总金额

如果我 select 一月的结果应该是

Month       Value    Quantity
December    3000      2
January     7000      2
February    18000     3 

我是LINQ的新手,请提供建议

Model -- Product
 public int Id { get; set; }
 public string? Name { get; set; }
 public int? Amount{ get; set; }
public DateTime CreatedDate { get; set; }

修改@KiranJoshi 的答案

public List<ProductQty> GetData(int month)
        {
            var now = DateTime.Now.Date;
            var startDate = DateTime.Now.AddMonths(-1);
            // https://stackoverflow.com/a/41765316/471213
            if (startDate.Day > 1)
                startDate = startDate.AddDays(-(startDate.Day-1));
            var endDate = DateTime.Now.AddMonths(1);
            // https://stackoverflow.com/a/4078999/471213
            endDate = endDate.AddDays(1-endDate.Day).AddMonths(1).AddDays(-1);


            var query = db.product.Where(x => (x.CreatedDate >= startDate&& x.CreatedDate <= endDate));

            var gquery = query.GroupBy(c => c.CreatedDate.Month).Select(x =>
            new ProductQty
            {
                Amount = x.Sum(x => x.Amount),
                Total = x.Count(),
                Month = x.Key
            }).ToList();

            var ret = new List<ProductQty>();

            for(var date = startDate; date <= endDate; date = date.AddMonths(1)) {
                var month = gquery.FirstOrDefault(x=>x.Month == date.Month && x.Year == date.Year);
                ret.add(month);
            }
            return ret;
        }


public struct ProductQty
    {
        public decimal Amount { get; set; }
        public decimal Total { get; set; }
        public int Month { get; set; }
    }

该解决方案(未编译,未测试,旨在提供设计师的想法)克服了万年历问题。

您不确定是否有特定月份的任何数据。 例如,假设一家企业整个 8 月都关门了,所以您绝对没有任何记录。

我选择使用struct并在第二个循环中使用FirstOrDefault ,以便在数据库的结果集不包含数据的情况下始终返回一个值。 如果假设数据库一个月内没有数据,则返回的行数是 2 比 3。

你真正想要的是返回零。 SQL 数据库通常不允许加入带有万年历的表

linq 查询看起来像这样:

public class ResultLine{

   public ResultLine() { }

   public string Month {get; set;}
   public int Value {get; set; }
   public int Quantity {get; set;}
}

List<ResultLine> result = Lines
    .GroupBy(l => l.CreatedDate)
    .Where(l=> t.CreatedDate >= urdate-1 && ...) // check how to parse dates so you can delete and add one month to compare dates
   .Select(cl => new ResultLine
            {
                Month  = cl.CreatedDate,
                Value  = cl.Sum(c => c.Amount),
                Quantity = cl.Count(),
            }).ToList();

您可以使用以下查询获取数据:

public List<ProductQty> GetData(int month)
        {
            int prevYear = DateTime.Now.Year;
            int nextYear = DateTime.Now.Year;
            int nextMonth = DateTime.Now.Month + 1;
            int prevMonth = DateTime.Now.Month - 1;
            if (nextMonth > 12)
            {
                nextYear += 1;
                nextMonth = 1;
            }
            if (prevMonth <= 0)
            {
                prevYear -= 1;
                prevMonth = 12;
            }

            DateTime prevMonthFirstDate = new DateTime(prevYear, prevMonth, 01);
            DateTime nextMonthEndDate = new DateTime(nextYear, nextMonth, DateTime.DaysInMonth(nextYear, nextMonth));

            var query = db.product.Where(x => (x.CreatedDate >= prevMonthFirstDate && x.CreatedDate <= nextMonthEndDate));

            var gquery = query.GroupBy(c => c.CreatedDate.Month).Select(x =>
            new ProductQty
            {
                Amount = x.Sum(x => x.Amount),
                Total = x.Count(),
                Month = x.Key
            }).ToList();

            return gquery;
        }

Model

public class ProductQty
    {
        public decimal Amount { get; set; }
        public decimal Total { get; set; }
        public int Month { get; set; }
    }

在此查询中,您将获取月份作为数字,因此根据您的要求将其转换为 html 中的月份。

暂无
暂无

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

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