C# 从Linq查询创建多个结果
我有一个相当独特的情况,我从来没有想过要这样做。我有一个Linq查询,它使用EF4.1从数据库返回数据。我想从每个查询结果中创建多个类似的相同签名匿名,甚至命名(如果需要) 下面是我现在使用的代码:C# 从Linq查询创建多个结果,c#,linq,C#,Linq,我有一个相当独特的情况,我从来没有想过要这样做。我有一个Linq查询,它使用EF4.1从数据库返回数据。我想从每个查询结果中创建多个类似的相同签名匿名,甚至命名(如果需要) 下面是我现在使用的代码: var data = getMyData().Select(x => new { GoalName = x.GoalType.Name, Start = x.Start
var data = getMyData().Select(x =>
new
{
GoalName = x.GoalType.Name,
Start = x.StartDate,
End = x.EndDate,
x.StartValue,
x.CheckIns
}).ToList();
var r1 = data.Select(x =>
new
{
title = x.GoalName,
start = x.Start.ToString(),
end = x.End.ToString(),
className = "hidden",
type = "goal"
});
var r2 = data.Select(x =>
new
{
title = string.Format("Start: {0:0.##}", x.StartValue),
start = x.Start.ToString(),
end = x.Start.ToString(),
className = "",
type = ""
});
var r3 = data.Select(x =>
new
{
title = "End",
start = x.End.ToString(),
end = x.End.ToString(),
className = "",
type = ""
});
var r4 = data.SelectMany(x => x.CheckIns)
.Select(y =>
new
{
title = y.CheckInValue.Value.ToString(),
start = y.CheckInDateTime.ToString(),
end = y.CheckInDateTime.ToString(),
className = "",
type = ""
});
var result = r1.Union(r2).Union(r3).Union(r4);
现在也许这是一个很好的方法,但我忍不住觉得我错过了什么
有更好的解决方案吗?尝试使用let关键字,它会对您有效。您可以使用yield创建一个迭代器,该迭代器还具有惰性评估的优点,不需要ToList。我创建了一个类型化的类结果来保存查询结果
private IEnumerable<Result> PerformQuery()
{
var results= getMyData().Select(x => new {GoalName = x.GoalType.Name,
Start = x.StartDate, End = x.EndDate, x.StartValue, x.CheckIns});
foreach (var result in results)
{
yield return new Result() { Title = result.GoalName, Start = result.Start.ToString(), End = result.End.ToString(), ClassName = "Hidden", Type = "Goal" };
yield return new Result() { Title = String.Format("Start: {0:0.##}",result.StartValue), Start = result.Start.ToString(), End = result.Start.ToString() }
yield return new Result() { Title = "End", Start = result.End.ToString(), End = result.End.ToString() };
foreach (var checkIn in result.CheckIns)
yield return new Result() { Title = checkIn.CheckInValue.Value.ToString(), Start = checkIn.CheckInDateTime.ToString(), End = checkIn.CheckInDateTime.ToString() };
}
}
我想你的一切都还可以 但是StevenzNPaul的建议没那么糟糕,下面是如何使用let关键字来存储不同的投影,然后分别选择结果,为简洁起见,我并没有投影所有字段,但你得到了要点:
var query = from x in data
let result1 = new {title = x.GoalName, start = x.Start}
let result2 = new {title = string.Format("Start: {0:0.##}", x.StartValue), start = x.Start}
let result3 = new {title = "End", start = x.End}
let checkins = x.CheckIns.Select(checkin => new { title = "...", start = checkin.Start })
from result in new[] { result1, result2, result3 }.Concat(checkins)
select result;
显然,这是否更好是一个偏好问题。此外,这将导致不同的排序,这可能对您来说是个问题,也可能不是问题。您可能希望重新格式化代码,以便让愿意帮助您的人更容易阅读。此外,您能否澄清您试图返回的内容?@Chris Pietschmann-代码已经格式化,只是行间没有空格。我想这是个人喜好。在任何情况下,从代码中可以明显看出我得到了什么,并且代码运行良好。我只是在寻找一种功能完全相同但效率更高的产品。你为什么用Union而不是Concat?看起来你只是想把它们连接起来,而不是计算它们的集合并集,这涉及到相互比较它们是否相等,对吗?我在ToString上的观点是,你不需要在很多地方这样做:你可以在第一次选择时这样做,或者,您可以在末尾添加另一个Select来执行此操作。让我们不要执行我需要的操作。Let允许您使用多个查询进行一个查询。我想要相反的方法,一个查询和多个结果集投射回一个结果中。这是一种有趣的方法,但似乎没有添加额外的抽象层,因此速度稍慢。我接受更正。我明白你的意思。这段代码看起来可能会导致创建几个额外的对象以及更多的选择。无论如何,这是一个有趣的解决方案。我认为它不会创建更多的对象。主要区别在于,使用此解决方案,您只需在输入列表数据上循环一次。额外的选择只会为“for循环体”添加更多权重。