2013-05-17 78 views
1

我正在尋找優雅的,可重複使用的解決方案,以解決一直困擾我多年的問題。因此,在linq-sql語句中使用自定義方法或委託

說我有我使用過的所有網站的一些業務邏輯:(沒有得到舉起來多麼簡單,這是,它可能是複雜的)

public DateTime ExpiryDate 
{ 
    get { return DateAdded.Date.AddMonths(ApplicationConfiguration.Rule3ExpiryLengthInMonths); } 
} 

而且一個LINQ聲明:

groupedByPatient.Count(x => 
         x.Max(a => System.Data.Objects.EntityFunctions.AddMonths(a.DateAdded, ApplicationConfiguration.Rule3ExpiryLengthInMonths)) 
         <= DateTime.Now); 

這個「已過期」的邏輯必須重複(可以理解)Expired不是db中的列。最終的結果是,我們最終在代碼中分散了業務邏輯。理想情況下,我們將有:

var count = groupedByPatient.Count(x => 
         x.Max(a => a.ExpiryDate) 
         <= DateTime.Now); 

只要從理論上講,你符合的LINQ的「C#」規則,你應該能夠抽象的代碼了,說:

public DateTime ExpiryDate 
    { 
     get { return System.Data.Objects.EntityFunctions.AddMonths(
       DateAdded, ApplicationConfiguration.Rule3ExpiryLengthInMonths).D } 
    } 
+0

我認爲這裏的困惑是在你使用groupedByPatient。這是你已經實現的結果還是它對DataContext.Patients [分組查詢]的引用。解決方案非常不同。 – Gats

回答

0

你爲什麼不創建extension method關於DateTime?這樣一來,只要你有一個約會,你可以直接調用,讓您的到期日:

static class DateTimeExtensions 
{ 
    public static DateTime ExpiryDate(this DateTime dte) 
    { 
     return dte.AddMonths(ApplicationConfiguration.Rule3ExpiryLengthInMonths); 
    } 
} 

如果我正確理解你的榜樣,DateAdded是表中的日期列,要從中找到期滿日期。然後,只是這樣做:

var count = groupedByPatient.Count(x => 
         x.Max(a => a.DateAdded.ExpiryDate()) <= DateTime.Now); 
+0

我正在尋找的解決方案不是如何做到這一點,而是如何在鏈接語句中使用c#方法。這種過期方法可以是任何事情。正如Linq to SQL站在當前這不能完成的,我正試圖想出一個很好的可重用解決方案。目的是將可重用的業務邏輯從Linq語句中抽象出來。 – GarethReid

+0

@GarethReid:當然,任何C#語句都可以與LINQ一起使用 - 但不一定與LINQ to Entity Framework或LINQ to SQL一起使用;特別是,如果您使用LINQ to * Objects *,則可以使用任何有效的C#。原因當然是,你的方法可以用於例如。LINQ to EF,它必須可以將你的LINQ查詢翻譯成一個EF查詢(它看起來很像SQL),但這通常是不可能的。因此,根據邏輯的複雜性,您可能必須從db中獲取所有對象,然後在生成的集合的查詢中使用C#方法。 –

0

我不是這個主題VS你已經把代碼中的樣本確定,但我敢肯定,這裏的第二點是你在找什麼。

如果你只想要一個物化查詢(你已經得到了數據後,即)的結果,然後使用擴展:

public static string ToExpiryDate(this DateTime date) 
{ 
    return date.AddMonths(ApplicationConfiguration.Rule3ExpiryLengthInMonths); 
} 

如果你想從一個IQueryable的範圍內的結果(由你的主題是什麼,我認爲你正在尋找),那麼你可以使用表達式:

public static Expression<Func<IEnumerable<YourEntity>, DateTime>> MaxExpiryDate = (y) => y.Max(
    System.Data.Objects.EntityFunctions.AddMonths(y.DateAdded, ApplicationConfiguration.Rule3ExpiryLengthInMonths) 
); 

然後將查詢看起來像:

var count = groupedByPatient.Count(x => x.YourEntities(MaxExpiryDate) <= DateTime.Now); 

注意:函數<>必須包含在表達式<>中,即使兩者似乎都可以工作,而不將其包裝在表達式中,查詢將在運行之前強制實現。通過在函數中放置表達式,我們告訴EF將其作爲查詢的一部分。

+0

我看到你在這裏做什麼。我玩了一下表情,但沒有運氣。我會玩一點,讓你知道。 – GarethReid

相關問題