我正在尝试编写一个LINQ查询,该查询获取Course
个实体及其映射的Skill
子项列表。它们与具有相应CourseId
和SkillId
的联接表相关联。我希望使用Skill
属性对Weight
个孩子进行排序,然后对SkillId
属性进行排序。我使用的是dot net core 2.0。
在查看有关如何在此处对子实体列表进行排序/排序的类似问题之后:
我想出了这个:
// Create query to get all courses with their skills
var coursesWithUnorderedSkills= db.Courses
.Include(i => i.Skills)
.ThenInclude(i => i.Skill);
// Order the skills for each course
await coursesWithUnorderedSkills.ForEachAsync(x => x.Skills = x.Skills
.OrderBy(o => o.Weight)
.ThenBy(o => o.SkillId)
.ToList());
// Get a list of courses from the query
var coursesWithOrderedSkills = await q.ToListAsync();
如何将此简化为单个查询,并且由于我在ToList
调用中呼叫ForEachAsync
,此查询是否会出现任何意外的性能问题?
模型
public class Course
{
[Key]
public int Id { get; set; }
public List<CourseSkill> Skills { get; set; }
}
public class CourseSkill
{
public Course Course { get; set; }
public int CourseId { get; set; }
public Skill Skill { get; set; }
public int SkillId { get; set; }
public int Weight { get; set; } = 0;
}
public class Skill
{
[Key]
public int Id { get; set; }
}
答案 0 :(得分:1)
对于评论感到抱歉,现在有了这个模型,我看起来很清楚你在寻找什么。你是对的,第二个声明将对技能列表进行排序。
无论如何,如果你想对子集合进行排序而不冒险通过IQueryable对数据库进行两次调用,你可以先异步获取课程列表,然后在内存中对技能进行排序:
// Create the list with all courses with their skills
var coursesWithSkills= await db.Courses
.Include(i => i.Skills)
.ThenInclude(i => i.Skill)
.ToListAsync();
// Order the skills for each course once data is in memory
foreach(x in coursesWithSkills)
{
x.Skills = x.Skills.OrderBy(o => o.Weight)
.ThenBy(o => o.SkillId)
.ToList());
}
如果你需要那个排序部分不阻塞当前线程,你应该使用Task.Run而不是异步操作来运行它,因为所有的排序工作都是CPU密集型的并且将完成在记忆中。但是我不会进行早期优化,我会保留foreach块,直到你看到任何性能问题。