Ste*_*ter 2 c# linq subquery quartz-scheduler quartz.net
绝对是一个LINQ新手,但对SQL和C#非常有经验,并想知道这在LINQ中是否可行.如果是这样,我可以在其他地方使用它,但我认为这将是一个很好的起点(并有助于简化/清理一些代码).这可能更通用,但我认为这可能是一个很好的现实生活中的例子,可以帮助解释.
快速背景:我正在做一个个人学习项目,构建一个调度程序,学习Spring.NET/DI,Fluent NHibernate,Quartz.NET,并尝试用TDD来完成我的专长.到目前为止已经学到了一吨.
Quartz.NET IScheduler对象具有这些属性(1)/方法(2)(假设为公共)...
string[] JobGroupNames { get; }
string[] GetJobNames(string groupName)
Trigger[] GetTriggersOfJob(string jobName, string groupName)
Run Code Online (Sandbox Code Playgroud)
假设触发器定义只是......
class Trigger
{
string Name { get; }
}
Run Code Online (Sandbox Code Playgroud)
我有一个类我正在尝试获取一个列表,其中包含如下构造函数(因为它一旦创建就不可变)...
class QuartzJob
{
public QuartzJob(Guid groupId, Guid jobId, IEnumerable<string> triggerNames)
}
Run Code Online (Sandbox Code Playgroud)
目前这就是我处理它的方式......
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;
}
Run Code Online (Sandbox Code Playgroud)
这种方式工作正常(虽然可能有点慢和复杂),但那些双foreach循环让我感到烦恼,因为我是"学习LINQ"踢,我认为这是一个很好的机会并尝试应用它.
不要求有人为我编写代码,因为这是一个学习项目(尽管你更受欢迎),只是想看看LINQ是否可以做这样的事情,如果有的话,寻找更多的信息...使用查询值调用方法,并使用这些值构建另一个查询.如果是这样的话,它会减少我在代码中其他地方的一些foreach循环.
谢谢!
在LINQ中做到这一点的关键是要明白.Select是你的朋友 - 但是一个可能会打你的朋友.我小子 你可以使用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);
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您更喜欢内联查询语言,它会更具可读性,如下所示:
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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2235 次 |
| 最近记录: |