2009-11-23 40 views
2

絕對是一個LINQ新手,但很有經驗的SQL和C#和想知道如果這是可能的LINQ。如果是這樣,我可以在其他地方使用它,但我認爲這將是一個很好的起點(並有助於簡化/清理一些代碼)。這可能會更普遍,但我認爲這可能是一個很好的現實生活中的例子,可以幫助解釋。使用LINQ查詢/子查詢多種方法(例如Quartz.NET團體,作業和觸發器)

快速背景:我做了個人的學習項目建設調度和學習Spring.NET/DI,功能NHibernate,Quartz.NET,並試圖讓我的壯舉溼TDD。到目前爲止學到了一噸。

甲Quartz.NET IScheduler對象具有這些特性(1)/方法(2)(假定公共)...

string[] JobGroupNames { get; } 
string[] GetJobNames(string groupName) 
Trigger[] GetTriggersOfJob(string jobName, string groupName) 

假設觸發器定義只是...

class Trigger 
{ 
    string Name { get; } 
} 

我有一個類,我試圖讓一個具有如下內容(因爲它是不可變的,一旦創建)一個構造函數列表...

class QuartzJob 
{ 
    public QuartzJob(Guid groupId, Guid jobId, IEnumerable<string> triggerNames) 
} 

目前,這是我如何處理它...

public IEnumerable<QuartzJob> GetQuartzInfo(IScheduler scheduler) 
{ 
    List<QuartzJob> list = new List<QuartzJob>(); 

    foreach (string grp in scheduler.JobGroupNames) 
    { 
     foreach (string job in scheduler.GetJobNames(grp)) 
     { 
      var triggerNames = scheduler 
       .GetTriggersOfJob(job, grp) 
       .ToList() 
       .ConvertAll(t => t.Name); 

      var qj = new QuartzJob(new Guid(grp), new Guid(job), triggerNames); 
      list.Add(qj); 
     } 
    }  
    return list; 
} 

這樣工作正常(雖然也許有點緩慢而複雜的)我,因爲我是一個「學習LINQ,但那些雙foreach循環錯誤「踢,我認爲這是一個很好的機會,並嘗試應用它。

沒有要求別人爲我寫代碼,因爲這是一個學習項目(儘管您更多的是歡迎),只是試圖看看LINQ是否可以做這樣的事情,如果是這樣,尋找一些有關它的更多信息...使用查詢值調用方法,並使用這些值構建另一個查詢。如果是這樣,它會減少我的代碼中其他地方的一些foreach循環。

謝謝!

回答

5

的關鍵在LINQ這樣做是瞭解。選擇是你的朋友 - 而是切切實實的朋友,誰可能會打你。我小子。您可以使用Select和它的堂兄SelectMany來即時轉換您的陣列。

public IEnumerable<QuartzJob> GetQuartzInfo(IScheduler scheduler) 
{ 
    IEnumerable<QuartzJob> jobs = scheduler.JobGroupNames.SelectMany( // Using SelectMany because there is an IEnumerable<QuartzJob> for each group and we want to flatten that. 
     groupName => scheduler.GetJobNames(groupName).Select( // Returns an IEnumerable<QuartzJob> for each group name found. 
      jobName => 
       // We're doing a lot in this new but essentially it creates a new QuartzJob for each jobName/groupName combo 
       new QuartzJob(new Guid(groupName), new Guid(jobName), 
        scheduler.GetTriggersOfJob(jobName, groupName).Select(trigger => trigger.Name) // This transforms the GetTriggersOfJob into an IEnumerable<string> for use in the constructor of QuartzJob 
        ))); 
    return new List<QuartzJob>(jobs); 
} 

或者,如果你喜歡的在線查詢語言這將會是一個有點更具可讀性,並期待這樣的:

public IEnumerable<QuartzJob> GetQuartzInfo(IScheduler scheduler) 
{ 
    IEnumerable<QuartzJob> jobs = from groupName in scheduler.JobGroupNames 
            from jobName in scheduler.GetJobNames(groupName) // stacking the two froms is the equivalent of SelectMany because the first select is defaulted as the result of the second. 
            select new QuartzJob(new Guid(groupName), new Guid(jobName), 
             // this sub-select is to get just the IEnumerable<string> of trigger names needed for the constructor. 
             (from trigger in scheduler.GetTriggersOfJob(jobName, groupName) 
             select trigger.Name)); 
    return new List<QuartzJob>(jobs); 
} 
+0

這正是我所期待的。你是我的英雄!你關心我是否信任你並鏈接到我的項目中的這篇文章? ( 這樣我就可以跟蹤在那裏我學到這些東西) 該項目是在http://code.google.com/p/dotnetjobscheduler/ – 2009-11-24 00:53:25

+0

不是。告訴他們所有投票給我的答案:)。 – 2009-11-24 00:59:05