Наиболее эффективно обрабатывать Create, Update, Delete с помощью Entity Framework Code First

Примечание. Я использую Entity Framework версии 5.

Внутри моего универсального репозитория у меня есть методы Add, Edit и Delete, как показано ниже:

public class EntityRepository<T> : IEntityRepository<T>
    where T : class, IEntity, new() {

    readonly DbContext _entitiesContext;

    public EntityRepository(DbContext entitiesContext) {

        if (entitiesContext == null) {

            throw new ArgumentNullException("entitiesContext");
        }

        _entitiesContext = entitiesContext;
    }

    //...

    public virtual void Add(T entity) {

        DbEntityEntry dbEntityEntry = _entitiesContext.Entry<T>(entity);
        if (dbEntityEntry.State != EntityState.Detached) {

            dbEntityEntry.State = EntityState.Added;
        }
        else {

            _entitiesContext.Set<T>().Add(entity);
        }
    }

    public virtual void Edit(T entity) {

        DbEntityEntry dbEntityEntry = _entitiesContext.Entry<T>(entity);
        if (dbEntityEntry.State == EntityState.Detached) {

            _entitiesContext.Set<T>().Attach(entity);
        }

        dbEntityEntry.State = EntityState.Modified;
    }

    public virtual void Delete(T entity) {

        DbEntityEntry dbEntityEntry = _entitiesContext.Entry<T>(entity);
        if (dbEntityEntry.State != EntityState.Detached) {

            dbEntityEntry.State = EntityState.Deleted;
        }
        else {

            DbSet dbSet = _entitiesContext.Set<T>();
            dbSet.Attach(entity);
            dbSet.Remove(entity);
        }
    }
}

Как вы думаете, хорошо ли реализованы эти методы? Особенно метод Add. Было бы лучше реализовать метод Add, как показано ниже?

public virtual void Add(T entity) {

    DbEntityEntry dbEntityEntry = _entitiesContext.Entry<T>(entity);
    if (dbEntityEntry.State == EntityState.Detached) {

        _entitiesContext.Set<T>().Attach(entity);
    }

    dbEntityEntry.State = EntityState.Added;
}

person tugberk    schedule 05.10.2012    source источник
comment
@CoffeeAddict Это EF 5.0.0. Сначала DB или сначала код, здесь это не имеет значения, я думаю, так как это общий код репозитория.   -  person tugberk    schedule 11.12.2012
comment
Вы можете использовать недавно выпущенную библиотеку, которая будет автоматически устанавливать состояние всех сущностей в графе сущностей. Вы можете прочитать мой ответ на аналогичный вопрос.   -  person Farhad Jabiyev    schedule 21.09.2016


Ответы (1)


Для добавления:

public bool Add<E>(E entity) where E : class
        {
            DataContext.Entry(entity).State = System.Data.EntityState.Added;
            Save();
        }

Для обновления:

 public bool Update<E>(E entity) where E : class
        {
            DataContext.Entry(entity).State = System.Data.EntityState.Modified;
            Save();
        }

Для удаления:

 public bool Delete<E>(E entity) where E : class
        {
            DataContext.Entry(entity).State = System.Data.EntityState.Deleted;
            Save();
        }

И закрытый метод Save(), который возвращает true или false, поэтому вы можете легко откатиться в контроллере в зависимости от результата.

private bool Save()
        {
            return DataContext.SaveChanges() > 0;                
        }

Это только часть моего общего репозитория. Он отлично работает в корпоративных приложениях.

ОБНОВЛЕНИЕ:

Detach влияет только на конкретный объект, переданный методу. Если отсоединяемый объект имеет связанные объекты в контексте объекта, эти объекты не отсоединяются.

EF будет автоматически присоединять отсоединенные объекты к графу при установке состояния сущности или при вызове SaveChanges().

Я действительно не знаю, почему вам нужно отделять объекты от контекста. Вы также можете использовать AsNoTracking() для загрузки сущностей из базы данных без их привязки к контексту.

person Matija Grcic    schedule 05.10.2012
comment
Что произойдет, если объект, который вы передаете в метод Add или Edit, находится в состоянии Detached? - person tugberk; 05.10.2012
comment
Это вместо того, чтобы иметь свойства IDbSet<T> в DbContext или репозитории? - person IAbstract; 24.04.2013
comment
Это было прекрасно. Спасибо! - person ncbl; 04.09.2013
comment
Какова цель where E : class - не знаете, что искать в Google, чтобы узнать больше об этом? - person Cody; 23.09.2013
comment
@Cody Это ограничение, поэтому аргумент типа должен быть ссылочным типом msdn.microsoft. com/en-us/library/d5x73970.aspx - person Matija Grcic; 23.09.2013
comment
Зачем нужен параметр типа? - person Ian Warburton; 19.05.2016