在MVC4中使用Linq进行过滤

3
我的表结构如下:
课程表 Course
ID    CourseName     

1       PHP
2       WORDPRESS

主课程

ID     MainCourseName
1       FoundationPhp
2       FoundationWordPress
3       Diploma

SubCourse

ID       MainCourseID   CourseID
 1           1             1
 2           2             2
 3           3             1
 3           3             2 

我有一个搜索场景,应该可以获取以下结果

当用户仅搜索PHP时,他应该得到以下结果

 MainCourseName    CourseCombination    
  FoundationPHP       PHP
  Diploma             PHP,WORDPRESS

当用户仅搜索“WORDPRESS”时,应该得到以下结果。
  MainCourseName           CourseCombination    
  FoundationWordPress       WORDPRESS
  Diploma                   PHP,WORDPRESS

当用户搜索PHP,WORDPRESS时,应显示以下结果。
   MainCourseName           CourseCombination
    Diploma                    PHP,WORDPRESS  

注意:如果有包含PHP & WORDPRESS的其他组合,也需要显示。例如这样一个组合:PHP,WORDPRESS,JAVA

我尝试了以下方法:

     List<int> CourseId={1,2}//means user searches by both PHP & WORDPRESS
     var courseList = _db.SubCourses
                      .AsEnumerable()
                      .Where(mcd => courseId.Contains(mcd.Course.Id))
                      .Select(mc => new RegistraionVM.clsCourseCodeSearch
                       {
                          CourseCode = mc.MainCourse.MainCourseName,
                          CourseCombination = string.Join(",", mc.MainCourse.SubCourse
                                                                .Select(mcd => mcd.Course.Name))                     

                        }).Distinct().Take(5).ToList();

上述查询返回以下结果。
  MainCourseName        CourseCombination    
  FoundationPHP         PHP
  FoundationWordPress   WORDPRESS
  Diploma               PHP,WORDPRESS

期望的结果是

  MainCourseName        CourseCombination        
  Diploma               PHP,WORDPRESS

如何实现上述结果。
2个回答

2

您需要首先按MainCourseID进行分组,然后使用.All()语句仅选择所有子课程均包含在筛选器中的项目。

var filter = new int[] { 1 }; // or new int[] { 1, 2 } etc

var results = list.GroupBy(x => x.MainCourseID).Select(x => new
{
    MainCourse = x.FirstOrDefault().MainCourse,
    SubCourseIDs = x.Select(y => y.Course.ID),
    SubCourseNames = x.Select(y => y.Course.CourseName)
}).Where(x => filter.All(y => x.SubCourseIDs.Contains(y))).Select(x => new RegistraionVM.clsCourseCodeSearch()
{
    CourseCode = x.MainCourse.MainCourseName,
    CourseCombination = String.Join(", ", x.SubCourseNames)
}).Take(5).ToList();

这个答案只会返回ID值,而不是名称,因为不清楚你将结果投影到哪个视图模型中 - 例如,如果过滤器是{1,2},则结果将是MainCourseName:3,CourseCombination:"1,2"。一旦您确认此代码返回了您期望的值,我可以修复它以显示名称。 - user3559349
1
已更新答案。如果我正确解释了您的模型,现在应该给出CourseCode:“Diploma”,CourseCombination:“PHP,WORDPRESS”,如果过滤器是{1,2} - user3559349
如果可能的话,请查看这个问题[无间隙发票号码创建] (http://stackoverflow.com/questions/38244666/sequentialgapless-invoice-number-creation)。 - ksg
1
@ksg,我倾向于同意Scott Chamberlain的评论。如果你想创建这个数字,在触发器中实现,但只与INSERT操作相关联。虽然我不明白为什么它们需要是连续的 - 它们应该只是唯一的。如果发票被删除,你将遇到问题。 - user3559349
谢谢您的评论,我会按照您说的去尝试。关于连续部分,是的,我的客户希望发票号码是唯一且连续的,否则他们可能会遇到法律问题。 - ksg
显示剩余2条评论

-1

PHP = 1 而且MainCourse 1和3都有课程PHP = 1 所以应该这样说:

FoundationPhp PHP Diploma PHP,WORDPRESS

否则我就不明白你的问题了。


是的,但如果用户搜索PHP,WORDPRESS,那么两个课程的组合应该只是结果。Foundation PHPFoundation WORDPRESS不会出现。 - ksg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接