2015-03-04 1 views
0

Я использую шаблон общего репозитория с единичной реализацией работы для моего проекта.Элемент работы Шаблон и обновление свойств коллекции объектов

Недавно я пришел к вопросу, который я не мог решить. Когда я пытаюсь обновить свойство коллекции сущности (т. Е. Добавить новый связанный объект) и вызвать обновление на моем 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(); 
} 

Я ожидаю, что этот код, чтобы создать новую компанию -> ServiceCategory и добавьте запись в базу данных. Когда я выполняю ту же операцию без Единицы работы, но используя сам DbContext, она работает.

Что я делаю неправильно с моей UoW & Реализация общего репозитория?

+0

Показать тело UnitOfwork.Commit() ... – st4hoo

+0

@ st4hoo отредактировал это сообщение, чтобы показать тело метода UnitOfWork.Commit(). – Alaminut

+0

@ Аламуните, поэтому я предполагаю, что компания имеет виртуальную коллекцию 'ServiceCategories', является ли метод' Get' ленивой или нетерпеливой загрузкой коллекции? – SOfanatic

ответ

0

Благодаря комментарию SOfanatic, проблема решена сейчас.

Я обновил свой метод BuildQuery GenericRepository, чтобы отразить предложение 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.

Смежные вопросы