我首先遇到有关EF 4.1代码的问题。 我试图用一个简化的例子来演示。
假设我们有一个包含States集合的Country类。 州集合包含学校集合。 学校是一个抽象的课程。 它有ElementarySchool和HighSchool的专业。
HighSchool拥有DrivingCourses的收藏属性。 DrivingCourses和所有其他数据成功保存到数据库中。
我的问题是当我加载Country类时,DrivingCourses集合仍然为null。 (其他一切都还可以)
据我所知,问题是因为当ef加载并填充HighSchool类时,它不知道课程集合。
我无法添加此映射,因为使用流畅的api静态反射,我只能映射(抽象)学校类的属性。
我正在使用默认的抽象配置:每个层次结构的表 如果有可能用EF 4.1解决我的问题,有人可以让我更聪明吗?
提前致谢, 桑德
答案 0 :(得分: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 { ... }
你有一个DbContext,其中包含public DbSet<Country> Countries { get; set; }
。
现在您要加载所有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上使用Load
不会更改问题。 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();
但这基本上和以前一样,并且它也没有解决在单个数据库往返中在第一个DrivingCourses
语句中加载Load
的问题。