2010-12-14 36 views
0

这是我目前的工作。Linqtosql查询:顶部日期..总数.. groupby orderby .. =有趣的东西:)

我有一个债务表(债务类型,签证/万事达卡等)和每月金额表(每种债务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); 

这是伟大的上市按月细分的数额,但它并没有解决我的没有报告当月债务量的问题然而。 So: 给我所有来自最新报告期的债务,并将它们总计(它们的清单也会很好)。

在一个侧面说明,如果它很重要,我使用EntityFramework对SQL数据库。此外,“MonthYear”是一个DateTime。

+0

我不明白“根据上次报告的每月债务数量获得总额的债务”,如果我们不需要猜测债务数额的存储位置,那将会很好。 – VVS 2010-12-14 23:49:43

+0

对不起,我想我应该添加更多的db结构...虽然下面的第一个答案看起来像它可能工作(现在尝试)。 – CraigF 2010-12-16 00:00:33

+0

我有2个表格,一个是债务类型清单(Id和Name),另一个是每个债务的债务清单(DebtId int32,“MonthYear”datetime,“DebtAmount”decimal)。 – CraigF 2010-12-16 00:17:28

回答

0

我会假设你MonthAmounts表的结构是,像这样:

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

如果不是从你的问题清楚是否有将只有一个一个给定的债务类型的记录&月/年组合与否。而且由于您明确表示MonthYearDateTime类型,我将假设每个月可能有特定债务类型的任何数量的记录。这种想法适合您需要组合在一起的单个交易表。如果我错了,请你澄清一下。

因此,这里需要查询:

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 

让我知道这是否是你想要的。

+0

现在测试,但这看起来正确的钱(没有双关语意图:)) – CraigF 2010-12-16 00:02:45

+0

任何想法为什么第二个查询会抛出:{“LINQ to Entities不能识别方法'System.Linq.IGrouping'2 [系统。 Int32,<> f__AnonymousType1'3 [System.Int32,System.Int32,System.Decimal]] 最后[IGrouping'2](System.Collections.Generic.IEnumerable'1 [System.Linq.IGrouping'2 [System.Int32 ,<> f__AnonymousType1'3 [System.Int32,System.Int32,System.Decimal]]])' 方法,并且此方法无法转换为存储表达式。“} – CraigF 2010-12-16 00:43:36

+0

@CraigF - 当EF(或LINQ-to-SQL等)不知道如何将LINQ语句转换为SQL查询时,会出现这类错误.LINQ-to-Objects可以运行这些查询,使所有你需要做的是强制查询针对对象而不是数据库运行,只需在'latest'查询中将'.ToArray()'添加到'codedMonthlyAmounts',你就会很好。 – Enigmativity 2010-12-16 10:45:12