如何在实体框架

时间:2015-09-27 17:13:06

标签: c# json entity-framework inheritance oftype

我有一个很大的问题,就是在Entity Framework中的单个查询中查询不同类型的继承子实体。我的主要目标是通过急切加载在单个JSON字符串中提供我的所有数据模型结构。棘手的一点是“继承的子类可能包含另一个继承的子类”。下面的例子将清楚地解释这种情况。

假设我有一个像这样的简单类结构:

public class Teacher
    {
        public int id { get; set; }
        public string fullname{ get; set; }
        //navigation properties
        public virtual HashSet<Course> courses{ get; set; }
    }

public class Course
    {
        public int id { get; set; }
        public string coursename{ get; set; }
        //foreign keys
        public int TeacherId{ get; set; }
        //navigation properties
        public virtual Teacher teacher{ get; set; }
        public virtual HashSet<Course> prerequisites{ get; set; }
    }

课程有一些子类GradedCourse和UngradedCourse B1或B2可能有一个子实体列表,包含B1或B2类型的实体。

public class GradedCourse : Course
    {
        public string gradeType{ get; set; }
    }

public class UngradedCourse: Course
    {
        public string successMetric { get; set; }
    }

现在通过这种结构,我想从我的WEBApi提供一个JSON结构,包括GradedCourse和UngradedCourse以及它们的子实体和特定字段。我有这样的查询,但它没有编译

db.Teachers.Select(t => new 
  { 
  t.id,
  t.fullName
  courses = t.courses.OfType<GradedCourses>()
            .Select(g => new
              {
                id = g.id,
                coursename = g.coursename,
                prerequisites = g.prerequisites, // this is the list of other subentities 
                gradeType = g.gradeType 
              }
             ).Concat(t.courses.OfType<UngradedCourses>()
                       .Select(u => new
                         {
                          id = u.id,
                          coursename = u.coursename,
                          prerequisites = g.prerequisites, // this is the list of other subentities 
                          successMetric= u.successMetric // subclass specific field
                         }
                        )
               )
  } 
)

问题在于汇总两种不同类型的对象(它们具有不同的字段,这是SQL UNION无法实现的)

我该如何处理?任何帮助都会打开我的脑海。在此先感谢专业人士:)

1 个答案:

答案 0 :(得分:0)

它不能编译,因为2组的元素类型不相同。所以你只需要在能够做任何事情之前使它们相同:

db.Teachers.Select(t => new 
{ 
 t.id,
 t.fullName
 courses = t.courses.OfType<GradedCourses>()
            .Select(g => new
            {
              id = g.id,
              coursename = g.coursename,
              prerequisites = g.prerequisites, // this is the list of other subentities 
              isGradedCourse = true,
              gradeTypeOrMetric = g.gradeType 
            }).Concat(t.courses.OfType<UngradedCourses>()
              .Select(u => new
                     {
                      id = u.id,
                      coursename = u.coursename,
                      prerequisites = g.prerequisites, // this is the list of other subentities 
                      isGradedCourse = false,
                      gradeTypeOrMetric= u.successMetric // subclass specific field
                     }))
              //finally select what of your choice
              .Select(e => new {
                  id = e.id,
                  coursename = e.coursename,
                  prerequisites = e.prerequisites,
                  gradeType = e.isGradedCourse ? e.gradeTypeOrMetric : "",
                  successMetric = e.isGradedCourse ? "" : e.gradeTypeOrMetric
              })
});

您仍然可以在服务器端执行查询,而不必将所有教师都拉到本地(然后能够转换实体 - LinqToEntity查询不支持)。