C# 将sql server中的linq查询转换为一个表
我有三张桌子。我想用C linq把它变成一张桌子。 例如:C# 将sql server中的linq查询转换为一个表,c#,sql-server,entity-framework,linq,C#,Sql Server,Entity Framework,Linq,我有三张桌子。我想用C linq把它变成一张桌子。 例如: Schedule: +------+--------+--------+ | Name | DateId | TaskId | +------+--------+--------+ | John | 2 | 32 | | John | 3 | 31 | | Mary | 1 | 33 | | Mary | 2 | 31 | | Tom | 1 |
Schedule:
+------+--------+--------+
| Name | DateId | TaskId |
+------+--------+--------+
| John | 2 | 32 |
| John | 3 | 31 |
| Mary | 1 | 33 |
| Mary | 2 | 31 |
| Tom | 1 | 34 |
| Tom | 2 | 31 |
| Tom | 3 | 33 |
+------+--------+--------+
日期:
任务:
我想要一张这样的桌子:
+--------+----------+----------+-----------+----------+
| Person | Monday | Tuesday | Wednesday | Thursday |
+--------+----------+----------+-----------+----------+
| John | | Homework | School | |
| Mary | Break | School | | |
| Tom | Teaching | School | Break | |
+--------+----------+----------+-----------+----------+
我想不出什么好办法来做这件事
任何建议都会有帮助
谢谢这叫做转置
var persons = new[] { new { name="John", dateId=2,taskId=32},
new { name="John", dateId=3,taskId=31},
new { name="Mary", dateId=1,taskId=33},
new { name="Mary", dateId=2,taskId=31},
new { name="Tom", dateId=1,taskId=34},
new { name="Tom", dateId=2,taskId=31},
new { name="Tom", dateId=3,taskId=33}
};
var dates = new[] { new { dateId=1, desc="Monday"},
new { dateId=2, desc="Tuesday"},
new { dateId=3, desc="Wednesday"},
new { dateId=4, desc="Thursday"},
new { dateId=5, desc="Friday"}
};
var tasks = new[] { new { taskId=31, desc="School"},
new { taskId=32, desc="Homework"},
new { taskId=33, desc="Break"},
new { taskId=34, desc="Teaching"}
};
var qry = from p in (from p in persons
join d in dates on p.dateId equals d.dateId
join t in tasks on (int)p.taskId equals (int)t.taskId
select new { name = p.name, monday = d.dateId == 1 ? t.desc : "", tuesday = d.dateId == 2 ? t.desc : "", wednesday = d.dateId == 3 ? t.desc : "", thursday = d.dateId == 4 ? t.desc : "", friday = d.dateId == 5 ? t.desc : "" })
group p by p.name into q
select new { q.Key, monday=q.Max(a => a.monday),tuesday=q.Max(a => a.tuesday), wednesday = q.Max(a=>a.wednesday), thursday = q.Max(a => a.thursday), friday=q.Max(a => a.friday)};
foreach ( var a in qry.ToList())
{
Console.WriteLine(String.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}",a.Key, a.monday, a.tuesday, a.wednesday, a.thursday, a.friday));
}
这叫做转置
var persons = new[] { new { name="John", dateId=2,taskId=32},
new { name="John", dateId=3,taskId=31},
new { name="Mary", dateId=1,taskId=33},
new { name="Mary", dateId=2,taskId=31},
new { name="Tom", dateId=1,taskId=34},
new { name="Tom", dateId=2,taskId=31},
new { name="Tom", dateId=3,taskId=33}
};
var dates = new[] { new { dateId=1, desc="Monday"},
new { dateId=2, desc="Tuesday"},
new { dateId=3, desc="Wednesday"},
new { dateId=4, desc="Thursday"},
new { dateId=5, desc="Friday"}
};
var tasks = new[] { new { taskId=31, desc="School"},
new { taskId=32, desc="Homework"},
new { taskId=33, desc="Break"},
new { taskId=34, desc="Teaching"}
};
var qry = from p in (from p in persons
join d in dates on p.dateId equals d.dateId
join t in tasks on (int)p.taskId equals (int)t.taskId
select new { name = p.name, monday = d.dateId == 1 ? t.desc : "", tuesday = d.dateId == 2 ? t.desc : "", wednesday = d.dateId == 3 ? t.desc : "", thursday = d.dateId == 4 ? t.desc : "", friday = d.dateId == 5 ? t.desc : "" })
group p by p.name into q
select new { q.Key, monday=q.Max(a => a.monday),tuesday=q.Max(a => a.tuesday), wednesday = q.Max(a=>a.wednesday), thursday = q.Max(a => a.thursday), friday=q.Max(a => a.friday)};
foreach ( var a in qry.ToList())
{
Console.WriteLine(String.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}",a.Key, a.monday, a.tuesday, a.wednesday, a.thursday, a.friday));
}
从这组数据开始:
var schedules = new[] { new { Name = "John", DateId = 2, TaskId = 32},
new { Name = "John", DateId = 3, TaskId = 31},
new { Name = "Mary", DateId = 1, TaskId = 33},
new { Name = "Mary", DateId = 2, TaskId = 31},
new { Name = "Tom", DateId = 1, TaskId = 34},
new { Name = "Tom", DateId = 2, TaskId = 31},
new { Name = "Tom", DateId = 3, TaskId = 33}
};
var dates = new[] { new { DateId = 1, Desc = "Monday"},
new { DateId = 2, Desc = "Tuesday"},
new { DateId = 3, Desc = "Wednesday"},
new { DateId = 4, Desc = "Thursday"},
new { DateId = 5, Desc = "Friday"}
};
var tasks = new[] { new { TaskId = 31, Desc = "School"},
new { TaskId = 32, Desc = "Homework"},
new { TaskId = 33, Desc = "Break"},
new { TaskId = 34, Desc = "Teaching"}
};
您可以执行以下操作:
var result = schedules
// First you join the three tables
.Join(dates, s => s.DateId, d => d.DateId, (s, d) => new {s, d})
.Join(tasks, s => s.s.TaskId, t => t.TaskId, (sd, t ) => new { Person = sd.s, Date = sd.d, Task = t })
// Then you Group by the person name
.GroupBy(j => j.Person.Name)
// Finally you compose the final object extracting from the list of task the correct task for the current day
.Select(group => new
{
Person = group.Key,
Monday = group.Where(g => g.Date.DateId == 1).Select(g => g.Task.Desc).FirstOrDefault(),
Tuesday = group.Where(g => g.Date.DateId == 2).Select(g => g.Task.Desc).FirstOrDefault(),
Wednesday = group.Where(g => g.Date.DateId == 3).Select(g => g.Task.Desc).FirstOrDefault(),
Thursday = group.Where(g => g.Date.DateId == 4).Select(g => g.Task.Desc).FirstOrDefault(),
Friday = group.Where(g => g.Date.DateId == 5).Select(g => g.Task.Desc).FirstOrDefault()
})
.ToList();
如果只想选择几天,可以返回包含字典的对象,而不是具有“每天”属性的对象
字典将包含键值对,键值表示日期,值表示任务
请参阅以下代码:
var filter = new[] {2, 3};
var filteredResult = schedules
.Join(dates, s => s.DateId, d => d.DateId, (s, d) => new{ s, d})
.Join(tasks, s => s.s.TaskId, t => t.TaskId, (sd, t) => new { Person = sd.s, Date = sd.d, Task = t })
.Where(x => filter.Contains(x.Date.DateId))
.GroupBy(x => x.Person.Name)
.Select(group => new
{
Person = group.Key,
TasksByDay = group.ToDictionary(o => o.Date.Desc, o => o.Task.Desc)
})
.ToList();
foreach (var item in filteredResult)
{
System.Console.WriteLine(item.Person);
foreach (var keyvaluepair in item.TasksByDay)
{
System.Console.WriteLine(keyvaluepair.Key + " - " + keyvaluepair.Value);
}
System.Console.WriteLine("---");
}
从这组数据开始:
var schedules = new[] { new { Name = "John", DateId = 2, TaskId = 32},
new { Name = "John", DateId = 3, TaskId = 31},
new { Name = "Mary", DateId = 1, TaskId = 33},
new { Name = "Mary", DateId = 2, TaskId = 31},
new { Name = "Tom", DateId = 1, TaskId = 34},
new { Name = "Tom", DateId = 2, TaskId = 31},
new { Name = "Tom", DateId = 3, TaskId = 33}
};
var dates = new[] { new { DateId = 1, Desc = "Monday"},
new { DateId = 2, Desc = "Tuesday"},
new { DateId = 3, Desc = "Wednesday"},
new { DateId = 4, Desc = "Thursday"},
new { DateId = 5, Desc = "Friday"}
};
var tasks = new[] { new { TaskId = 31, Desc = "School"},
new { TaskId = 32, Desc = "Homework"},
new { TaskId = 33, Desc = "Break"},
new { TaskId = 34, Desc = "Teaching"}
};
您可以执行以下操作:
var result = schedules
// First you join the three tables
.Join(dates, s => s.DateId, d => d.DateId, (s, d) => new {s, d})
.Join(tasks, s => s.s.TaskId, t => t.TaskId, (sd, t ) => new { Person = sd.s, Date = sd.d, Task = t })
// Then you Group by the person name
.GroupBy(j => j.Person.Name)
// Finally you compose the final object extracting from the list of task the correct task for the current day
.Select(group => new
{
Person = group.Key,
Monday = group.Where(g => g.Date.DateId == 1).Select(g => g.Task.Desc).FirstOrDefault(),
Tuesday = group.Where(g => g.Date.DateId == 2).Select(g => g.Task.Desc).FirstOrDefault(),
Wednesday = group.Where(g => g.Date.DateId == 3).Select(g => g.Task.Desc).FirstOrDefault(),
Thursday = group.Where(g => g.Date.DateId == 4).Select(g => g.Task.Desc).FirstOrDefault(),
Friday = group.Where(g => g.Date.DateId == 5).Select(g => g.Task.Desc).FirstOrDefault()
})
.ToList();
如果只想选择几天,可以返回包含字典的对象,而不是具有“每天”属性的对象
字典将包含键值对,键值表示日期,值表示任务
请参阅以下代码:
var filter = new[] {2, 3};
var filteredResult = schedules
.Join(dates, s => s.DateId, d => d.DateId, (s, d) => new{ s, d})
.Join(tasks, s => s.s.TaskId, t => t.TaskId, (sd, t) => new { Person = sd.s, Date = sd.d, Task = t })
.Where(x => filter.Contains(x.Date.DateId))
.GroupBy(x => x.Person.Name)
.Select(group => new
{
Person = group.Key,
TasksByDay = group.ToDictionary(o => o.Date.Desc, o => o.Task.Desc)
})
.ToList();
foreach (var item in filteredResult)
{
System.Console.WriteLine(item.Person);
foreach (var keyvaluepair in item.TasksByDay)
{
System.Console.WriteLine(keyvaluepair.Key + " - " + keyvaluepair.Value);
}
System.Console.WriteLine("---");
}
请尝试将您的问题格式化为可读格式,这显然不是您应该如何提问的方式。的可能重复。您需要此透视表,您可以参考此[链接]请尝试将您的问题格式化为可读格式,这显然不是您应该问的问题。的可能重复。您需要从此透视表中获取数据透视表,您可以参考此[链接]是否有方法动态选择列?例如,如果我现在只想看星期一和星期五,那么以后我只想看星期三。我是否能够传入一个变量来过滤我想要的列。我只想选择我想要的列。@sylanter根据你的评论,我更新了我的答案,请看一下有没有办法动态选择列?例如,如果我现在只想看星期一和星期五,那么以后我只想看星期三。我是否能够传入一个变量来过滤我想要的列。我只想选择我想要的列。@sylanter根据你的评论,我更新了我的答案,请看一下有没有办法动态选择列?例如,如果我现在只想看星期一和星期五,那么以后我只想看星期三。我是否能够传入一个变量来过滤我想要的列。我只想选择我想要的列。@sylanter,据我所知,该列必须是硬编码的。有办法动态选择列吗?例如,如果我现在只想看星期一和星期五,那么以后我只想看星期三。我是否能够传入一个变量来过滤我想要的列。我只想选择我想要的列。@sylanter,据我所知,该列必须是硬编码的。