我正在尝试在ProjectVersions列表上进行基本的预先加载,其中每个ProjectVersion都有一个FieldValues和ChildProjects列表。我希望在加载ProjectVersions时将FieldValues和ChildProjects及其所有属性一起加载,但似乎在我的代码中,当经历每个ProjectVersion时,它仍然会访问数据库以获取这些集合(检查sql server profiler)。任何指针都会有所帮助。
var publishedList = Repository.Find<Project>().//a bunch of wheres and selects
IEnumerable<ProjectVersion> publishedList = published
.Include(x => x.FieldValues)
.Include(x => x.ChildProjects)
.ToList();
//EDIT: the context is hidden behind a generic Repository. Below are some details:
public class Repository : IRepository
{
internal readonly IDataContext _context;
public Repository(IDataContext context)
{
_context = context;
_context.Committed += _context_Committed;
_context.Deleted += _context_Deleted;
}
public IQueryable<T> Find<T>() where T : class, IEntity
{
return _context.Repository<T>();
}
}
public class EfDataContext : IDataContext
{
public IQueryable<T> Repository<T>() where T : class, IEntity
{
var table = _context.Set(typeof(T));
WrappedFieldsObjectQuery<T>(table.Cast<T>().AsExpandable()));
return table.Cast<T>().AsExpandable();
}
}
public class MsmDbContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(type =>
type.IsClass &&
type.BaseType.IsGenericType &&
type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (var config in typesToRegister.Select(Activator.CreateInstance))
{
modelBuilder.Configurations.Add((dynamic)config);
}
base.OnModelCreating(modelBuilder);
}
}
public class ProjectMapping : EntityTypeConfiguration<Project>
{
public ProjectMapping()
{
HasOptional(p => p.LastChangedBy).WithMany(p => p.ProjectsChanged).WillCascadeOnDelete();
HasRequired(p => p.CreatedBy).WithMany(p => p.ProjectsCreated).WillCascadeOnDelete();
HasRequired(d => d.Account).WithMany(p => p.Projects).WillCascadeOnDelete();
HasRequired(d => d.PinType).WithMany(p => p.Projects).HasForeignKey(p => p.PinType_Id).WillCascadeOnDelete();
}
}
public static class RepositoryFactory
{
public static IRepository CreateRepository()
{
return CreateEfRepository();
}
internal static IRepository CreateEfRepository()
{
return new Repository(new EfDataContext(new MsmDbContext()));
}
}
答案 0 :(得分:0)
好的,我看不到您的完整查询,但在您的评论中,您写了一些关于select
的内容。一旦使用Include()
进行自定义投影,EF就会忽略Select()
语句,我猜这就是为什么急切加载不起作用的原因。而不是Include()
,尝试将要加载的属性添加到投影中,例如
Repository.Find<Project>()
.Select(p => new { project = p, p.FieldValues, p.ChildProjects })
.AsEnumerable().Select(p => p.project).ToList()
这种投影将负责加载您的数据,您不需要Include()
。
答案 1 :(得分:0)
实际上,我通过直接使用DataContext来实现它。不知何故,存储库正在搞砸它。