【问题标题】:Unit of Work Pattern And Updating Entity Collection Properties工作单元模式和更新实体集合属性
【发布时间】:2015-05-05 12:04:59
【问题描述】:

我正在为我的项目使用具有工作单元实现的通用存储库模式。

最近我遇到了一个我无法解决的问题。当我尝试更新实体的集合属性(即:添加新的关联实体)并在我的 UoW 上调用更新(将其委托给存储库和显然是 EF)时,它不会保存到数据库中。

我的通用存储库:

public class GenericRepository<TEntity> where TEntity : class
    {
        internal MyDBContext context;
        internal DbSet<TEntity> dbSet;

        public GenericRepository(MyDBContext context)
        {
            this.context = context;
            this.dbSet = context.Set<TEntity>();
        }

        internal virtual IQueryable<TEntity> BuildQuery(Expression<Func<TEntity,bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "")
        {
            IQueryable<TEntity> query = dbSet.AsNoTracking();
            foreach (var include in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(include);
            }

            if (filter != null)
                query = query.Where(filter);

            if (orderBy != null)
                return orderBy(query);

            return query;
        }

        public virtual IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "")
        {
            IQueryable<TEntity> query = BuildQuery(filter, orderBy, includeProperties);
            return query.ToList();
        }

    public virtual void Update(TEntity entity)
    {
        dbSet.Attach(entity);
        context.Entry<TEntity>(entity).State = EntityState.Modified;
    }
}

我的工作单元实施

public class UnitOfWork : IDisposable
{
    //code removed for clarity

    public GenericRepository<CorporateServiceCategory> ServiceCategories
    {
        get
        {
            if(this.serviceCategoryRepository == null)
            {
                serviceCategoryRepository = new GenericRepository<CorporateServiceCategory>(context);
            }

            return serviceCategoryRepository;
        }
    }

    public void Commit()
    {
       context.SaveChanges();
    }
}

我想做的是:

using(var unit = new UnitOfwork())
{
    //unit.Companies is a generic repository instance for Company entities.
    var company = unit.Companies.Get(filter: f => f.Id == 1).SingleOrDefault();

    company.ServiceCategories.Add(new ServiceCategory {Name = "Demo"});
    unit.Companies.Update(company);

    //This is a call to context.SaveChanges();
    unit.Commit();
}

我希望这段代码创建一个新的 Company -> ServiceCategory 关联并向数据库添加一条记录。当我在没有工作单元但使用 DbContext 本身的情况下执行相同的操作时,它可以工作。

我的 UoW 和通用存储库实施有什么问题?

【问题讨论】:

  • 显示你的 UnitOfwork.Commit() 方法体...
  • @st4hoo 编辑了帖子以显示 UnitOfWork.Commit() 方法体。
  • @Alaminut 所以我猜公司实体有一个ServiceCategories 的虚拟集合,Get 方法是延迟加载集合还是急切加载集合?
  • @SOfanatic,正确。公司实体具有虚拟 ICollection 属性。在上下文中启用延迟加载和更改跟踪,Get 方法仅封装对 DbSet 的调用。您可以在帖子中看到实现。我已经在那里共享了 GenericRepository 类和 Get 方法。
  • @Alaminut 我认为由于您是延迟加载并且在 Get 内部您正在执行 AsNoTracking 它可能不会自动更新集合。尝试立即加载 ServiceCategories,然后使用该集合。

标签: c# ef-code-first entity-framework-6 unit-of-work


【解决方案1】:

感谢SOfanatic的评论,问题已经解决了。

我已经更新了我的 GenericRepository 的 BuildQuery 方法以反映 SOfanatic 的建议并且它奏效了。

这是更新后的 BuildQuery 方法:

internal virtual IQueryable<TEntity> BuildQuery(Expression<Func<TEntity,bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "")
        {
            IQueryable<TEntity> query = this.context.IsReadOnly ? dbSet.AsNoTracking() : dbSet;
            foreach (var include in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(include);
            }

            if (filter != null)
                query = query.Where(filter);

            if (orderBy != null)
                return orderBy(query);

            return query;
        }

DbContext.IsReadOnly 是我添加到我的 DbContext 实现中的自定义属性。这样,如果我想以一种“只读”模式(仅选择)加载实体,我会禁用延迟加载、代理生成和更改跟踪,因此它会稍微提高 EF 性能。

【讨论】:

    猜你喜欢
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多