我有三个表:课程,CourseLocations,CourseSchedules
每个课程可以在一个或多个地点举行(1对多) 每个位置可以托管一个或多个计划(1对多)
我需要获得所有具有Schedules.Date>的课程,唯一名称。今天还显示表CourseSchedules
中包含的日期的MAX值我目前的linq代码是:
var courses = (from c in db.Courses
join cl in db.CourseLocations on c.CourseID equals cl.CourseID
join cs in db.CourseSchedules on cl.CourseLocationID equals cs.CourseLocationID
where c.CourseStatusID == 1 && c.DeleteDate == null && ((c.CourseCategoryID == 1 && cs.EndDate >= courseEndDateFilter) || (c.CourseCategoryID == 3))
select new
{
c.CourseID,
CourseName = c.Name,
CourseEndDate = cs.EndDate
}).Distinct().OrderBy(o => o.CourseCategoryID).ThenBy(o => o.CourseName);
其中courseEndDateFilter是用于定义过滤日期的变量。
上述问题的问题在于我得到了所有重复的课程,而不仅仅是那个MAX值为cs.EndDate的课程
有办法(有效率)吗?
答案 0 :(得分:2)
@Ehsan是对的。您需要一个group by然后获取EndDate的最大值。鉴于以下模型:
public class Course
{
public int CourseID { get; set; }
public string Name { get; set; }
public int CourseStatusID { get; set; }
public int CourseCategoryID { get; set; }
public DateTime? DeleteDate { get; set; }
}
public class CourseLocation
{
public int CourseLocationID { get; set; }
public int CourseID { get; set; }
}
public class CourseSchedules
{
public int CourseLocationID { get; set; }
public DateTime EndDate { get; set; }
}
我在内存对象中创建了以下内容:
var courses = new List<Course>
{
new Course { CourseID = 1, Name = "Test1", CourseCategoryID = 1, CourseStatusID = 1, DeleteDate = null },
new Course { CourseID = 2, Name = "Test2", CourseCategoryID = 1, CourseStatusID = 1, DeleteDate = null },
new Course { CourseID = 3, Name = "Test3", CourseCategoryID = 3, CourseStatusID = 1, DeleteDate = null }
};
var courseLocations = new List<CourseLocation>
{
new CourseLocation{ CourseID = 1, CourseLocationID = 1 },
new CourseLocation{ CourseID = 2, CourseLocationID = 1 },
new CourseLocation{ CourseID = 3, CourseLocationID = 1 },
new CourseLocation{ CourseID = 1, CourseLocationID = 2 },
new CourseLocation{ CourseID = 2, CourseLocationID = 2 },
new CourseLocation{ CourseID = 3, CourseLocationID = 2 }
};
var courseSchedules = new List<CourseSchedules>
{
new CourseSchedules { CourseLocationID = 1, EndDate = DateTime.Now.AddDays(10) },
new CourseSchedules { CourseLocationID = 1, EndDate = DateTime.Now.AddYears(1) }
};
然后查询将获得Max EndDate:
var result = (from c in courses
join cl in courseLocations on c.CourseID equals cl.CourseID
join cs in courseSchedules on cl.CourseLocationID equals cs.CourseLocationID
where c.CourseStatusID == 1 && c.DeleteDate == null &&
(c.CourseCategoryID == 1 && cs.EndDate >= DateTime.Now || c.CourseCategoryID == 3)
select new
{
c.CourseID,
CourseName = c.Name,
CourseEndDate = cs.EndDate,
c.CourseCategoryID
})
.GroupBy(arg => new
{
arg.CourseID,
arg.CourseName,
arg.CourseCategoryID
})
.Select(grouping => new
{
grouping.Key.CourseID,
grouping.Key.CourseName,
CourseEndDate = grouping.Max(arg => arg.CourseEndDate),
grouping.Key.CourseCategoryID
})
.OrderBy(o => o.CourseCategoryID)
.ThenBy(o => o.CourseName);
答案 1 :(得分:0)
我不确定这会起作用,因为它不像我可以实际编译它。
我立即看到的问题是你在基地过滤了一些东西,其中一些不包括位置,但你想要从这些位置的日期......
var courses = (from c in db.Courses
join cl in db.CourseLocations on c.CourseID equals cl.CourseID
join cs in db.CourseSchedules on cl.CourseLocationID equals cs.CourseLocationID
where c.CourseStatusID == 1 && c.DeleteDate == null && (c.CourseCategoryID == 3 ||
db.CourseLocations.Any(cl => cl.CourseID equals c.CourseID &&
db.CourseSchedules.Any(cs => cs.CourseLocationID equals cl.CourseLocationID &&
((c.CourseCategoryID == 1 && cs.EndDate >= courseEndDateFilter))
)
))
select new
{
c.CourseID,
CourseName = c.Name,
CourseEndDate = db.CourseSchedules.Where(cs => db.CourseLocations.Any(cl => cl.CourseID equals c.CourseID && cs.CourseLocationID equals cl.CourseLocationID)).Max(cs => cs.EndDate),
c.CourseCategoryID
});