2016-09-26 1 views
0

J'ai problème avec insert et mise à jour par générique référentiel, en insertion générique ou le mettre à jour hasnot problème, mais dans plusieurs à plusieurs je reçois l'erreur à insérer:Insérer/Mettre à jour plusieurs à plusieurs avec dépôt générique

Une L'objet entité ne peut pas être référencé par plusieurs instances de IEntityChangeTracker.

mise à jour:

La relation entre les deux objets ne peuvent pas être définis parce qu'ils sont attachés à des objets différents ObjectContext.

mes codes sont

Interface

public interface IGenericRepository<TEntity>:IDisposable 
    { 
void Insert(TEntity entity); 
void Update(TEntity entity); 
} 

classe générique

public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class 
      { 
       private ApplicationDbContext context=null; 
       private DbSet<TEntity> dbSet=null; 
       public GenericRepository() 
       { 
        this.context = new ApplicationDbContext(); 
        this.dbSet = context.Set<TEntity>(); 
       } 
       public GenericRepository(ApplicationDbContext context) 
       { 
        this.context = context; 
        this.dbSet = context.Set<TEntity>(); 
       } 

       public virtual void Insert(TEntity entity) 
       { 
Error is here---> this.context.Set<TEntity>().Add(entity); 
        // dbSet.Add(entity); 
        context.SaveChanges(); 
       } 

       public virtual void Update(TEntity entity) 
       { 
Error is here---> dbSet.Attach(entity); 
        context.Entry(entity).State = EntityState.Modified; 
        context.SaveChanges(); 
       } 

     } 

et les codes de contrôle sont

 private IGenericRepository<Blog> _Repository = null; 
     private IGenericRepository<BlogTag> _RepositoryTag = null; 
     private IGenericRepository<BlogCategory> _RepositoryCategory = null; 

     public BlogsController() 
     { 

      this._Repository = new GenericRepository<Blog>(new DbContext()); 
      this._RepositoryTag = new GenericRepository<BlogTag>(new DbContext()); 
      this._RepositoryCategory = new GenericRepository<BlogCategory>(new DbContext()); 
     } 

    public async Task<ActionResult> Create([Bind(Include = "BlogID,BlogTitle,BlogContent,VisitCount,Preview")] Blog blog 
       ,string[] SelectedTags,string[] SelectedCategories, HttpPostedFileBase files) 
      { 

       if (SelectedTags != null) 
       { 
        blog.BlogTags = new List<BlogTag>(); 
        foreach (var tag in SelectedTags) 
        { 
         var tagToAdd = _RepositoryTag.GetById(int.Parse(tag)); 
         blog.BlogTags.Add(tagToAdd); 
        } 
       } 
       if (SelectedCategories != null) 
       { 
        blog.BlogCategories = new List<BlogCategory>(); 
        foreach (var cat in SelectedCategories) 
        { 
         var catToAdd = _RepositoryCategory.GetById(int.Parse(cat)); 
         blog.BlogCategories.Add(catToAdd); 
        } 
       } 

       if (ModelState.IsValid) 
       { 
        blog.DateTimeInsert = DateTime.UtcNow; 
        blog.DateTimeModify = DateTime.UtcNow; 
        blog.ImagePath= files != null ? Path.GetFileName(files.FileName) : ""; 
        blog.BlogContent = HttpUtility.HtmlEncode(blog.BlogContent); 

        _Repository.Insert(blog); 

        return RedirectToAction("Index"); 
       } 

       ViewBag.BlogTags = new SelectList(_RepositoryTag.Get(), "BlogTagID", "TagName"); 
       ViewBag.BlogCategories = new SelectList(_RepositoryCategory.Get(), "BlogCategoryID", "CategoriesName"); 

       return View(blog); 
      } 


      [HttpPost] 
      [ValidateAntiForgeryToken] 
      public async Task<ActionResult> Edit([Bind(Include = "BlogID,BlogTitle,BlogContent,VisitCount,Preview")] Blog blog 
       , string[] SelectedTags, string[] SelectedCategories, HttpPostedFileBase files) 
      { 

       if (Request["BlogID"] == null) 
       { 
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
       } 
       int id = int.Parse(Request["BlogID"].ToString()); 
       var blogsToUpdate = _Repository.Query(i => i.BlogID == id, null).Include(t => t.BlogTags).Include(t => t.BlogCategories).Single(); 

       if (TryUpdateModel(blogsToUpdate, "", 
        new string[] { "BlogID", "BlogTitle", "BlogContent", "VisitCount","Preview" })) 
       { 
        try 
        { 


         UpdateInstructorCourses(SelectedTags, SelectedCategories, blogsToUpdate); 

         blogsToUpdate.DateTimeModify = DateTime.UtcNow; 
         blogsToUpdate.DateTimeInsert = DateTime.UtcNow; 
         blogsToUpdate.BlogContent = HttpUtility.HtmlEncode(blogsToUpdate.BlogContent); 

         await _Repository.UpdateAsync(blogsToUpdate, d => d.BlogTitle, d => d.VisitCount, d => d.BlogContent, d => d.ImagePath); 

         return RedirectToAction("Index"); 
        } 
        catch (RetryLimitExceededException /* dex */) 
        { 
         //Log the error (uncomment dex variable name and add a line here to write a log. 
         ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator."); 
        } 
       } 
       AssignedDDLCHKBoxValues(blogsToUpdate); 
       return View(blogsToUpdate); 
      } 

      private void UpdateInstructorCourses(string[] SelectedTags, string[] SelectedCategories, Blog blogsToUpdate) 
      { 
       if (SelectedTags == null) 
       { 
        blogsToUpdate.BlogTags = new List<BlogTag>(); 
        return; 
       } 
       if (SelectedCategories == null) 
       { 
        blogsToUpdate.BlogCategories = new List<BlogCategory>(); 
        return; 
       } 

       var SelectedTagsHS = new HashSet<string>(SelectedTags); 
       var SelectedCategoriesHS = new HashSet<string>(SelectedCategories); 
       var blogTags = new HashSet<int>(blogsToUpdate.BlogTags.Select(c => c.BlogTagID)); 

       foreach (var tag in _RepositoryTag.Get()) 
       { 
        if (SelectedTagsHS.Contains(tag.BlogTagID.ToString())) 
        { 
         if (!blogTags.Contains(tag.BlogTagID)) 
         { 
          blogsToUpdate.BlogTags.Add(tag); 
         } 
        }//if 
        else 
        { 
         if (blogTags.Contains(tag.BlogTagID)) 
         { 
          blogsToUpdate.BlogTags.Remove(tag); 
         } 
        }//else 
       }//foreach tag 


       var blogcategories = new HashSet<int> 
        (blogsToUpdate.BlogCategories.Select(c => c.BlogCategoryID)); 
       foreach (var Category in _RepositoryCategory.Get()) 
       { 
        if (SelectedCategoriesHS.Contains(Category.BlogCategoryID.ToString())) 
        { 
         if (!blogcategories.Contains(Category.BlogCategoryID)) 
         { 
          blogsToUpdate.BlogCategories.Add(Category); 
         } 
        }//if 
        else 
        { 
         if (blogcategories.Contains(Category.BlogCategoryID)) 
         { 
          blogsToUpdate.BlogCategories.Remove(Category); 
         } 
        }//else 
       }//foreach skill 
      } 
+0

Où est-ce que votre code contient une exception? Cette exception est levée lorsque vous avez des objets suivis par différents contextes, et vous essayez d'utiliser l'objet d'un contexte via l'autre. Par exemple, si l'objet A est inséré dans la base de données via le contexte A, puis créez l'objet B en utilisant le contexte B et associez l'objet A à l'objet B et appelez savechanges dans chaque contexte, vous obtiendrez l'exception. – victor

+0

dans l'insertion je reçois l'erreur ici this.context.Set () .Add (entity); et mettez à jour cette ligne dbSet.Attach (entity); , je dois mentionner que j'ai 3 instance de 3 balise de repository, catégorie et blog mais je ne peux pas comprendre est l'objet que je le remplis est valide et avec hors référentiel il fonctionne de toute façon avez-vous une suggestion comment puis-je gérer cela ? – hesam

Répondre

0

Votre problème est que vous utilisez plusieurs contextes pour travailler avec une seule Entité. Sur votre constructeur de contrôleur que vous avez ces lignes:

this._Repository = new GenericRepository<Blog>(new DbContext()); 
this._RepositoryTag = new GenericRepository<BlogTag>(new DbContext()); 
this._RepositoryCategory = new GenericRepository<BlogCategory>(new DbContext()); 

Ici, vous créez trois dépôts 9QUE sont censés travailler ensemble) avec 3 contextes différents.

Après cela, vous passez à lire à partir du référentiel RepositoryTag, ici:

var tagToAdd = _RepositoryTag.GetById(int.Parse(tag)); 

Lorsque vous faites cela, l'objet tagToAdd s'attache au contexte intérieur RepositoryTag. Si vous déboguez votre liste BlogTags où vous ajoutez cette tagToAdd vous verrez que vous avez un proxy dynamique, ce qui signifie que cet objetc est attaché à un contexte.

Après cela, vous utilisez un autre contexte pour remplir catégorie référentiel, ici:

var catToAdd = _RepositoryCategory.GetById(int.Parse(cat)); 
blog.BlogCategories.Add(catToAdd); 

Maintenant, votre objet blog a des références à 2 contextes différents: celui que vous avez utilisé pour charger les balises (RepositoryTag), et celui que vous avez utilisé pour charger la catégorie du blog (RepositoryCategory).

Enfin, vous essayez de Inser le blog usgin un troisième contexte:

_Repository.Insert(blog); 

Ce lèveront une exception, car EF ne peut pas fonctionner avec de multiples contextes comme celui-ci.

Pour résoudre ce problème, il suffit d'instancier un contexte avant que les dépôts, et le transmettre à tous les dépôts yout, comme ceci:

this.context = new DbContext(); // The context you need to use for all operations you are performing here. 
this._Repository = new GenericRepository<Blog>(this.context); 
this._RepositoryTag = new GenericRepository<BlogTag>(this.context); 
this._RepositoryCategory = new GenericRepository<BlogCategory>(this.context); 

Maintenant, n'oubliez pas que vous devez disposer de vos contextes. C'est pourquoi l'approche la plus recommandée et la plus courante consiste à utiliser un code comme celui-ci:

using (var ctx = new DbContext()) { 

    var repo = new GenericRepository<Blog>(ctx); 
    var repoTag = new GenericRepository<BlogTag>(ctx); 
    var repoCategory = new GenericRepository<BlogCategory>(ctx); 

    <the rest of your code where you build the `blog` object> 

    ctx.SaveChanges(); 
} 
+0

merci pour votre aide;) c'est vrai qu'il fonctionne maintenant;) – hesam