工作单元模式和更新实体集合属性

Unit of Work Pattern And Updating Entity Collection Properties

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

最近遇到一个无法解决的问题。当我尝试更新实体的集合 属性(即:添加新的关联实体)并在我的 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 和通用存储库实施有什么问题?

感谢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 实现中的自定义 属性。这样,如果我想以一种 "read-only" 模式(仅选择)加载实体,我会禁用延迟加载、代理生成和更改跟踪,因此它会稍微提高 EF 性能。