EF 4.1抽象集合加载问题

问题描述

| 首先我有关于EF 4.1代码的问题。 我试图用一个简化的例子来演示。 假设我们有一个Country类,其中包含一个States集合。 州收藏包含学校收藏。 学校是一门抽象课。 它具有ElementarySchool和HighSchool的专长。 HighSchool具有DrivingCourses的集合属性。 DrivingCourses和所有其他数据已成功保存到数据库中。 我的问题是,当我加载Country类时,DrivingCourses集合仍然为空。 (其他都可以) 据我了解,问题是因为当ef加载并填充HighSchool类时,它不知道课程集合。 我无法添加此映射,因为使用流利的api的静态反射,我只能映射(抽象)School类的属性。 我正在使用认配置进行抽象:每个层次结构的表 如果可以使用EF 4.1解决我的问题,有人可以照亮我吗? 提前致谢, 桑多尔     

解决方法

        如果我正确理解了您的描述,则您的模型大致如下所示(我省略了关键属性,依此类推):
public class Country
{
    public ICollection<State> States { get; set; }
}

public class State
{
    public ICollection<School> Schools { get; set; }
}

public abstract class School { ...  }

public class ElementarySchool : School { ... }

public class HighSchool : School
{
    public ICollection<DrivingCourse> DrivingCourses { get; set; }
}

public class DrivingCourse { ... }
并且您有一个包含
public DbSet<Country> Countries { get; set; }
的DbContext。 现在,您要加载所有
Countries
(或国家的过滤集合),包括所有导航属性(尤其是
DrivingCourses
)。 我不知道是否可以通过一次单次往返数据库(通过急于加载所有集合)来实现。一个需要多次往返的解决方案可能是这样的:
// Load all Countries including `States` and `Schools` collection
// but not the `DrivingCourses` collection
var countryList = context.Countries
    .Include(c => c.States.Select(s => s.Schools))
    .ToList();

// Create in-memory list of all loaded Schools of type HighSchool
IEnumerable<HighSchool> highSchoolList =
    countryList.SelectMany(c =>
                  c.States.SelectMany(s => s.Schools.OfType<HighSchool>()));

// Explicitely load the DrivingCourses one by one
foreach (var item in highSchoolList)
    context.Entry(item).Collection(h => h.DrivingCourses).Load();
只是第一个想法。可能有更好的解决方案。 编辑 在“国家/地区” DbSet上使用ѭ5不会改变问题。
Load
ToList()
相同,但没有实际返回结果,只是将实体加载到上下文中。上面的代码可以这样重写:
context.Countries.Include(c => c.States.Select(s => s.Schools)).Load();

IEnumerable<HighSchool> highSchoolList =
    context.Countries.Local.SelectMany(c =>
                  c.States.SelectMany(s => s.Schools.OfType<HighSchool>()));

foreach (var item in highSchoolList)
    context.Entry(item).Collection(h => h.DrivingCourses).Load();
但这与以前基本相同,并且也无法解决在单个数据库往返中的第一个“ 5”语句中加载“ 3”的问题。