简体   繁体   English

Linq到实体组的DateTime

[英]Linq to Entities Group By DateTime

I want to be able to get sales from the last 12 months, grouped by month. 我希望能够获得过去12个月中按月分组的销售额。 Here's what I have so far: 这是我到目前为止的内容:

Class Definition: 类定义:

        public DateTime DateSold { get; set; }
        public int Month { get; set; }

        public int USDNumberItemsSold { get; set; }
        public int GBPNumberItemsSold { get; set; }
        public int EURNumberItemsSold { get; set; }
        public int TotalNumberItemsSold { get { return USDNumberItemsSold + GBPNumberItemsSold + EURNumberItemsSold; } }

        public decimal USDRevenueTotal { get; set; }
        public decimal GBPRevenueTotal { get; set; }
        public decimal EURRevenueTotal { get; set; }
        public decimal OverallEarnings { get { return USDRevenueTotal + GBPRevenueTotal + EURRevenueTotal; } }

My Linq query is as follows: 我的Linq查询如下:

List<MonthlySales> monthlySales = (from sale in Sales
                                   orderby sale.DateSold descending
                                   group sale by sale.DateSold.Month into ds
                                   select new MonthlySales
                                   {
                                       DateSold = ds.Key,
                                       USDNumberItemsSold = ds.Where(it => it.USDCut.HasValue).Where(it => it.USDCut != 0).Count(),
                                       GBPNumberItemsSold = ds.Where(it => it.GBPrCut.HasValue).Where(it => it.GBPCut != 0).Count(),
                                       EURNumberItemsSold = ds.Where(it => it.EURCut.HasValue).Where(it => it.EURCut != 0).Count(),
                                       USDRevenueTotal = PerformCurrencyConversion(ds.Sum(it => it.USDCut.HasValue ? it.USDCut.Value : 0), 0M, 0M, reportRequest.BaseCurrency, endDate),
                                       GBPRevenueTotal = PerformCurrencyConversion(0M, ds.Sum(it => it.GBPCut.HasValue ? it.GBPCut.Value : 0), 0M, reportRequest.BaseCurrency, endDate),
                                       EURRevenueTotal = PerformCurrencyConversion(0M, 0M, ds.Sum(it => it.EURCut.HasValue ? it.EURCut.Value : 0), reportRequest.BaseCurrency, endDate),
                        }).Take(12).ToList();

I get the following error with this: 我收到以下错误:

Cannot implicitly convert type 'int' to 'System.DateTime' 无法将类型'int'隐式转换为'System.DateTime'

because obviously DateTime.Now.Month is an int. 因为显然DateTime.Now.Month是一个int。

I tried using the following: 我尝试使用以下内容:

Month = ds.Key

Where 'Month' is an int. 其中“月”为整数。 This was okay but for display purposes I don't have the year or things like that. 没关系,但出于显示目的,我没有年份或类似内容。

Can anyone offer any advice? 谁能提供任何建议?

Thanks. 谢谢。

What I would recommend would be to set the key to the first of the month in question, that way you also have the year information present (which you will need since you want the last 12 months). 我建议将密钥设置为有问题的月份的第一天,这样,您还可以看到年份信息(因为您需要最近的12个月,所以需要该信息)。

...
group sale by sale.DateSold.Date.AddDays(-(sale.DateSold.Day - 1)) into ds
orderby ds.Key descending
...

You also want to order by after the grouping instead of before, since grouping uses hash of keys instead of values, so you might not get the same ordering. 您还希望在分组之后而不是之前进行排序,因为分组使用键的哈希而不是值,因此您可能无法获得相同的排序。

Why don't you group by DateTime, so you will be able to set « DateSold » with « ds.Key ». 为什么不按DateTime分组,因此可以使用«ds.Key»设置«DateSold»。
And if you want the Month of the DateTime store in the Key, you can just « ds.Key.Month ». 而且,如果您希望将DateTime的月份存储在密钥中,则只需«ds.Key.Month»。

I would suggest introducing a new type to represent YearMonth if that's what you need (see my question in comments). 如果您需要的话,我建议您引入一种新的类型来表示YearMonth (请参阅我的问题以评论)。

BTW: If you are grouping by month only, then you can have problems in case when you get overlapping data, eg the data set contains data for 201101 and 201201 - both would be grouped together. 顺便说一句:如果仅按月份分组,那么当您获得重叠数据时可能会遇到问题,例如,数据集包含201101201201数据-两者将被分组在一起。 When you do the grouping by yearMonth this should not be an issue. 当您按yearMonth进行分组时,这应该不是问题。

The new type would be pretty basic (could be a struct): 新类型将是非常基本的(可以是结构):

public class YearMonthSold
{
    public int Year {get; set;}
    public int Month {get; set;}
}

MonthlySales would get this property: MonthlySales将获得此属性:

public YearMonthSold DateSold { get; set; }

And the LINQ query would need updated to make use of it: LINQ查询将需要更新才能使用它:

List<MonthlySales> monthlySales = (from sale in Sales
                        orderby sale.DateSold descending
                        group sale by new {Year = sale.DateSold.Year, Month = sale.DateSold.Month} into ds
                        select new MonthlySales
                        {
                            DateSold = new YearMonthSold {Year = ds.Key.Year, Month = ds.Key.Month},
                            (...)
                        })
                       .Take(12)
                       .ToList();

EDIT: Or as suggested by SPFiredrake: 编辑:或由SPFiredrake建议:

List<MonthlySales> monthlySales = (from sale in Sales
                        orderby sale.DateSold descending
                        group sale by new YearMonthSold {Year = sale.DateSold.Year, Month = sale.DateSold.Month} into ds
                        select new MonthlySales
                        {
                            DateSold = ds.Key,
                            (...)
                        })
                       .Take(12)
                       .ToList();

I don't know the code for the Sale object, but it doesn't seem that it should be affected by this change in any way. 我不知道Sale对象的代码,但是似乎它不会以任何方式受到此更改的影响。

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

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