0

我将使用实体框架和ASP.NET MVC应用程序将一个博客插入到我的数据库中。如果我想将实体添加到上下文中,则我在下面的代码的最后一行出现了此错误。通过插入数据库引用多个实例的实体使用EF

InvalidOperationException的实体对象不能由IEntityChangeTracker多个实例被引用。

这里是我的代码:

public class AdminController : Controller 
{ 
    [HttpPost] 
    public ActionResult CreateBlog(BlogViewModel vm) 
    { 
     try 
     { 
      _blogService.Insert(new Blog() 
      { 
       Titel = vm.Titel, 
       Beschrijving = vm.Beschrijving, 
       Content = (vm.Actie.ToLower() == "publiceer" ? true : false), 
       Verwijderd = false, 
       Auteur = UserManager.FindById(User.Identity.GetUserId()) 
      }); 
     } 
     catch (Exception ex) 
     { 
      Console.Write(ex.Message); 
     } 

     return RedirectToAction(nameof(Blog)); 
    } 

    public ApplicationUserManager UserManager 
    { 
     get 
     { 
      return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
     } 
     private set 
     { 
      _userManager = value; 
     } 
    } 

    public AdminController(ApplicationUserManager userManager, IBlogService blog) 
    { 
     UserManager = userManager; 
     _blogService = blog; 
    } 
} 

public class BlogService : IBlogService 
{ 
    public void Insert(Blog blog) 
    { 
     _blogRepo.Insert(blog); 
     _blogRepo.SaveChanges(); 
    } 
} 

public class BlogRepo : GenericRepo<Blog> 
{ 
    public override Blog Insert(Blog blog) 
    { 
     context.Entry(blog.Auteur).State = EntityState.Unchanged; 
     return dbSet.Add(blog); // --> on this line 
    } 
} 

你能找到我,我做了什么问题?提前致谢。

+1

做你的UserManager和你blogService共享相同的DbContext。如果不是那么用户拥有2个上下文。 – tschmit007

+1

每个请求应该只有一个上下文实例。将其定义为控制器上的私有字段,并手动将其注入到'UserManager'和'BlogService'实例中,或使用依赖注入容器来管理生命周期和注入。 –

+0

@ tschmit007:否每次只有一个'dbContext'。 –

回答

2

我假设你的实体模型看起来像:

public class Blog 
{ 
    [Key] 
    public int Id { get; set; } 

    [Required] 
    // etc 
    public string Titel { get; set; } 

    public string Beschrijving { get; set; } 

    public bool Content { get; set; } 

    public bool Verwijderd { get; set; } 

    public ApplicationUser Auteur { get; set; } 
} 

你为什么不只是AuteurId属性添加到您的实体类。通过这种方式,您将避免获取用户实体(UserManager.FindById(User.Identity.GetUserId()))的附加查询。

public class Blog 
{ 
    [Key] 
    public int Id { get; set; } 

    [Required] 
    // etc 
    public string Titel { get; set; } 

    public string Beschrijving { get; set; } 

    public bool Content { get; set; } 

    public bool Verwijderd { get; set; } 

    [ForeignKey("Auteur")] 
    public string AuteurId { get; set; } 

    public virtual ApplicationUser Auteur { get; set; } 
} 

,然后在动作的代码会像

_blogService.Insert(new Blog() 
{ 
    Titel = vm.Titel, 
    Beschrijving = vm.Beschrijving, 
    Content = (vm.Actie.ToLower() == "publiceer" ? true : false), 
    Verwijderd = false, 
    AuteurId = User.Identity.GetUserId() 
}); 
+1

是的。因为它是跟踪两次的'ApplicationUser Auteur'。在添加博客时,一次通过UserManger的上下文,一次通过存储库的上下文。 –

相关问题