【问题标题】:why isn't eager loading working in Entity Framework为什么在实体框架中不急切加载工作
【发布时间】:2016-06-17 03:18:09
【问题描述】:

我正在尝试在 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()));
            }
        }

【问题讨论】:

  • 你能发布更详细的查询吗?尤其是涉及到的 DbContext 会很有帮助。
  • @FlorianHaider 嗯,是的,DbContext 隐藏在一个非常通用的 Repository 模式后面,我会尝试看看是否可以发布相关代码。

标签: entity-framework eager-loading


【解决方案1】:

好的,我看不到您的完整查询,但在您的 cmets 中您写了一些关于 select 的内容。只要您使用Select() 进行自定义投影,EF 就会忽略Include() 语句,我猜这就是急切加载不起作用的原因。而不是Include(),尝试添加你想要加载到你的投影的属性,比如

Repository.Find<Project>()
.Select(p => new { project = p, p.FieldValues, p.ChildProjects })
.AsEnumerable().Select(p => p.project).ToList()

这样投影将负责加载您的数据,您不需要Include()。

【讨论】:

    【解决方案2】:

    实际上,我只是通过直接使用 DataContext 来实现它。不知何故,存储库搞砸了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-09
      • 2012-02-07
      • 1970-01-01
      • 2012-09-10
      • 1970-01-01
      • 2011-05-03
      相关资源
      最近更新 更多