简体   繁体   English

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

[英]Unit of Work Pattern And Updating Entity Collection Properties

I'm using generic repository pattern with unit of work implementation for my project. 我正在使用通用存储库模式和我的项目的工作单元实现。

Recently I've come to an issue which I could not solve. 最近我遇到了一个我无法解决的问题。 When I try to update an entity's collection property (ie: Add a new associated entity) and call update on my UoW (to delegate it to repository and obviously EF) it does not save to the database. 当我尝试更新实体的集合属性(即:添加新的关联实体)并在我的UoW上调用update(将其委托给存储库,显然是EF)时,它不会保存到数据库中。

My generic repository: 我的通用存储库:

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;
    }
}

My Unit of Work implementation 我的工作单位实施

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();
    }
}

What I'm trying to do is: 我想要做的是:

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();
}

I expect this code to create a new Company -> ServiceCategory association and add a record to the database. 我希望这段代码能够创建一个新的Company - > ServiceCategory关联并向数据库添加一条记录。 When I do the same operation without Unit of Work but using DbContext itself, it works. 当我在没有工作单元的情况下执行相同的操作但使用DbContext本身时,它可以工作。

What am I doing wrong with my UoW & Generic Repository implementation? 我的UoW和通用存储库实现有什么问题?

Thanks to SOfanatic's comment, the problem has solved now. 感谢SOfanatic的评论,问题现在已经解决了。

I've updated my GenericRepository's BuildQuery method to reflect SOfanatic's suggestion and it worked. 我已经更新了我的GenericRepository的BuildQuery方法来反映SOfanatic的建议并且它有效。

Here is the updated BuildQuery method: 这是更新的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 is a custom property I added to my DbContext implementation. DbContext.IsReadOnly是我添加到我的DbContext实现的自定义属性。 That way if I want to load entities in a kind of "read-only" mode (only selects) I disable lazy loading, proxy generation and change tracking so it increases EF performance a bit. 这样,如果我想以一种“只读”模式加载实体(仅选择),我禁用延迟加载,代理生成和更改跟踪,以便稍微提高EF性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用Entity Framework 5和存储库模式和工作单元过滤内部集合 - Filtering inner collection with Entity Framework 5 and Repository pattern and Unit of Work 实体框架,存储库模式,工作单元和测试 - Entity Framework, Repository Pattern, Unit of Work and Testing 使用存储库模式更新实体框架中的集合的导航属性 - Updating navigation properties that are collections in Entity Framework with Repository pattern 工作单元/存储库模式以及使用EF更新实体 - Unit of Work/Repository pattern and updating entities using EF 使用单例存储库和工作单元模式时,附加实体时出错 - Error in attaching entity when using singleton Repository and Unit of Work Pattern 用于发布实体的 Asp.Net 核心存储库和工作单元模式 - Asp.Net core Repository and Unit Of Work Pattern for Posting an entity 使用Unity for Work of Unit / Repository模式创建Entity Framework对象 - Creating Entity Framework objects with Unity for Unit of Work/Repository pattern EntityFramework:通过工作单元模式为每个请求保留实体上下文 - EntityFramework: Hold entity context per request via Unit of Work pattern 在工作单元模式中检测到实体框架自引用循环 - Entity framework self referencing loop detected in Unit of work pattern 带有工作单元模式的实体框架和ADO.NET - Entity Framework and ADO.NET with Unit of Work pattern
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM