[英]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.