web-dev-qa-db-fra.com

Mise à jour des enregistrements à l'aide d'un modèle de référentiel avec Entity Framework 6

J'écris une application de blog simple et j'essaie d'établir des opérations CRUD dans mon modèle de référentiel générique, mais je reçois une erreur sur ma méthode de mise à jour qui dit:

'System.Data.Entity.DbSet' ne contient pas de définition pour 'Entry' et aucune méthode d'extension 'Entry' acceptant un premier argument de type 'System.Data.Entity.DbSet' n'a pu être trouvée (manque-t-il une directive using ou une référence d'assemblage?)

J'ai suivi un article qui expliquait comment "faux" Entry () en ajoutant un niveau d'indirection supplémentaire sur DbContext. Cependant, dans MVC 5, nous héritons de: IdentityDbContext et non DbContext. J'ai essayé d'implémenter le correctif des auteurs, mais l'erreur persiste.

Ma question

Comment puis-je ajouter une méthode de mise à jour à mon référentiel dans Entity Framework 6 à l'aide d'IdentityDbContext? Si nous ne sommes pas censés le faire de cette façon, comment puis-je mettre à jour un enregistrement avec ce modèle?

Je dois noter que toutes les autres méthodes fonctionnent comme prévu.

Mon référentiel générique:

public class BlogEngineRepository<T> : IRepository<T> where T : class
    {
        protected DbSet<T> DbSet;

        public BlogEngineRepository(DbContext dataContext)
        {
            DbSet = dataContext.Set<T>();
        }

        #region IRepository<T> Members

        public void Insert(T entity)
        {
            DbSet.Add(entity);
        }

        public void Delete(T entity)
        {
            DbSet.Remove(entity);
        }

        public void Update(T entity)
        { 

           DbSet.Entry(entity).State = System.Data.Entity.EntityState.Modified;

        }

        public IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate)
        {
            return DbSet.Where(predicate);
        }

        public IQueryable<T> GetAll()
        {
            return DbSet;
        }

        public T GetById(int id)
        {
            return DbSet.Find(id);
        }

        #endregion
    }
16
Dan Beaulieu

La mise à jour devrait ressembler à ( développant la réponse de Dan Beaulie ):

[HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Edit([Bind(Include = "Id,Title,IntroText,Body,Modified,Author")] Post post)
{
    using (UnitOfWork uwork = new UnitOfWork())
    {
        post.Modified = DateTime.Now;
        uwork.PostRepository.Update(post);

        uwork.Commit();

        return RedirectToAction("Index");
    }
}

RepositoryPattern ressemble à ceci:

public class BlogEngineRepository<T> : IRepository<T> where T : class
{
  public BlogEngineRepository(DbContext dataContext)
  {
    DbSet = dataContext.Set<T>();
    Context = dataContext;
  }

  public T Update(T entity)
  {
     DbSet.Attach(entity);
     var entry = Context.Entry(entity);
     entry.State = System.Data.EntityState.Modified;
  }
}

Vous pouvez voir une explication complète de la réponse pour moyen efficace de mettre à jour la liste des entités pour plus d'informations sur les détails d'une simple mise à jour.

14
Erik Philips

Ok, j'ai compris ça. La raison pour laquelle il n'y a pas de méthode de mise à jour dans les nouveaux modèles de référentiel (Entity Framework 6) est parce que il n'y en a pas besoin =. Vous récupérez simplement votre enregistrement par identifiant, apportez vos modifications, puis validez/enregistrez.

Par exemple, voici ma méthode d'édition POST de mon postController:

[HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Edit([Bind(Include = "Id,Title,IntroText,Body,Modified,Author")] Post post)
{
    using (UnitOfWork uwork = new UnitOfWork())
    {
        Post edit = uwork.PostRepository.GetById(post.Id);
        edit.Title = post.Title;
        edit.IntroText = post.IntroText;
        edit.Body = post.Body;
        edit.Modified = DateTime.Now;

        uwork.Commit();

        return RedirectToAction("Index");
    }
}

RepositoryPattern ressemble à ceci:

public class BlogEngineRepository<T> : IRepository<T> where T : class
{
    protected DbSet<T> DbSet;

    public BlogEngineRepository(DbContext dataContext)
    {
        DbSet = dataContext.Set<T>();
    } 

    public void Insert(T entity)
    {
        DbSet.Add(entity);
    }

    public void Delete(T entity)
    {
        DbSet.Remove(entity); 
    }

    public IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate)
    {
        return DbSet.Where(predicate);
    }

    public IQueryable<T> GetAll()
    {
        return DbSet;
    }

    public T GetById(int id)
    {
        return DbSet.Find(id);
    } 
}
19
Dan Beaulieu