2010-12-14 77 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