Linqtosql查询:顶级日期..总数.. groupby orderby .. =有趣的东西:)

时间:2010-12-14 23:40:52

标签: linq linq-to-entities

这是我目前正在做的事情。

我有一个带债务表的数据库(债务类型,签证/万事达卡等)和月度金额表(每种债务的月度金额12月签证金额未付等)。

我如何使用LinQ根据上次报告的每月债务金额(不一定是所有情况下的当月)来查询数据库以获得总债务。

到目前为止,我已经尝试过这个:

(from M in MonthlyAmounts
group M by new {M.MonthYear.Month, M.MonthYear.Year} into D
orderby D.Key.Month descending
select D).Take(1);

哪个列出按月分类的金额很有用,但这并不能解决我当前未报告的债务金额问题。 所以: 从最新的报告期间给我所有的债务并将它们总计(它们的列表也很好)。

另外,如果重要的话,我正在使用EntityFramework来对抗SQL数据库。另外,“MonthYear”是DateTime。

1 个答案:

答案 0 :(得分:0)

我将假设你的MonthAmounts表的结构是这样的:

public class MonthlyAmount
{
    public DateTime MonthYear { get; set;}
    public string DebtType { get; set;}
    public decimal DebtAmount { get; set;}
}

如果您的问题不清楚,对于给定的债务类型是否只有一个记录?月/年组合与否。既然你已明确表示MonthYear属于DateTime类型,我将假设每月给定债务类型可能有任意数量的记录。这种情况符合您将需要组合在一起的单个交易表的想法。如果我错了,请你澄清一下。

以下是所需的查询:

var codedMonthlyAmounts =
    from ma in MonthlyAmounts
    let MonthCode =
        ma.MonthYear.Year * 12
        + ma.MonthYear.Month
        - 1
    select new
    {
        MonthCode,
        ma.DebtType,
        ma.DebtAmount,
    };

var latest = 
    from cma in codedMonthlyAmounts
    group cma by cma.DebtType into gcmas
    let DebtType = gcmas.Key
    let current = gcmas
        .GroupBy(gcma => gcma.MonthCode)
        .OrderBy(ggcma => ggcma.Key)
        .Last()
    let DebtAmount = current.Sum(c => c.DebtAmount)
    let monthCode = current.Key
    let year = monthCode / 12
    let month = monthCode % 12 + 1
    let MonthYear = new DateTime(year, month, 1)
    select new MonthlyAmount()
    {
        DebtType = DebtType,
        MonthYear = MonthYear,
        DebtAmount = DebtAmount,
    };

如果您想测试这是否有效,请使用以下代码:

var MonthlyAmounts = new List<MonthlyAmount>();

var now = DateTime.Now;

MonthlyAmounts.Add(new MonthlyAmount()
    { MonthYear = now,
        DebtType = "Visa", DebtAmount = 1.2M, });
MonthlyAmounts.Add(new MonthlyAmount()
    { MonthYear = now.Subtract(TimeSpan.FromDays(2)),
        DebtType = "Visa", DebtAmount = 42.0M, });
MonthlyAmounts.Add(new MonthlyAmount()
    { MonthYear = now.Subtract(TimeSpan.FromDays(31)),
        DebtType = "MC", DebtAmount = 50.95M, });
MonthlyAmounts.Add(new MonthlyAmount()
    { MonthYear = now.Subtract(TimeSpan.FromDays(33)),
        DebtType = "Visa", DebtAmount = 3.1415M, });

//insert above `codedMonthlyAmounts` & `latest` queries here.

var format = "{0} @ {1:MMM} {1:yyyy} = {2:#,##0.00}";
foreach (var x in latest)
{
    Console.WriteLine(format,
        x.DebtType,
        x.MonthYear,
        x.DebtAmount);
}

Console.WriteLine("Total = {0:#,##0.00}",
    latest.Sum(l => l.DebtAmount));

测试代码的输出是:

Visa @ Dec 2010 = 43.20 
MC @ Nov 2010 = 50.95 
Total = 94.15

请告诉我这是否是你想要的。