一个简单的实体框架DbContext:
class SchoolDbContext : DbContext
{
public DbSet<Teacher> Teachers {get; set;}
public DbSet<Student> Students {get; set;}
}
要求。请给我老师的人数和学生的人数。
或者更具挑战性:“给我所有老师的名字,给我所有学生的生日”
通常需要两个查询才能执行此操作。根据以下答案,可以在一个查询中使用SQL进行此操作:
答案就像:
SELECT id, startdate, enddate , '-' AS point_id
FROM sarcshiftcentertable
UNION
SELECT id, startdate, enddate, point_id
FROM sarcshiftpointtable
但是可以在一个查询中使用LINQ做类似的事情吗?
答案将我引向Queryable.Union的方向。但是,此函数期望两个集合具有相同的输入类型。
所以我应该在结合之前选择一些共同点,
在这种情况下为object
var result = dbContext.Teachers.Select(teacher => teacher.Name).Cast<object>()
.Union(dbContext.Students.Select(student => student.BirthDay).Cast<object>())
// TODO select?
现在序列中的每个DateTime都是学生的生日。每个字符串都是老师的名字。
另一种可能性是选择一个新班级:
var result = dbContext.Teachers.Select(teacher => new
{
TeacherName = teacher.Name,
StudentBirthDay = null,
})
.Union(dbContext.Students.Select(student => new
{
TeacherName = null,
StudentBirthDay = student.BirthDay,
}))
// TODO: select?
现在,我可以通过检查其他属性是否等于null来检测某项是TeacherName还是StudentBirthDay。
但是如何继续?我如何得到一个像这样的物体:
new
{
TeacherNames = ...
StudentBirthdays = ...
}
或
new
{
TeacherCount = ...
StudentCount = ...
}
答案 0 :(得分:0)
使用异步方法,这可能是一件容易的事,而且可能更高效
async Task<IEnumerable<string>> GetTeacherNames()
{
using (var context = CreateContext(fromConfiguration))
{
return await context.Teachers.Select(teacher => teacher.Name).ToListAsync();
}
}
async Task<IEnumerable<DateTime>> GetStudentsBirthdays()
{
using (var context = CreateContext(fromConfiguration))
{
return await context.Students.Select(student => student.BirthDay).ToListAsync();
}
}
用法
var teacherTask = GetTeacherNames();
var studentsTask = GetStudentsBirthdays();
await Task.WhenAll(teacherTask, studentsTask);
var allTeacherNames = teacherTask.Result;
var allStudentsBirthdays = studentsTask.Result;
例如,如果教师查询花费2秒,学生花费3秒,那么两个异步查询将花费大约3秒。