我开发了一个系统,其中可以将许多材料(代码为Matetiaal)添加到广告中(在代码Zoeker中).这种关系很多很多.在这里你得到了我的课程结构.
+-------------------------------------+ many to many +-------------------------------+ | Zoeker | <--------------> | Materiaal | +------------+------------------------+ +---------+---------------------+ | ID | int | | ID | int | | Materialen | ICollection<Materiaal> | | Zoekers | ICollection<Zoeker> | | Titel | string | | Naam | string | +------------+------------------------+ +---------+---------------------+
void Insert(Zoeker zoeker,string[] materialen) { foreach (string m in materialen) { Materiaal mat = materiaalRepo.GetByName(m); if (mat == null) { mat = materiaalRepo.Insert(new Materiaal(m)); } zoeker.Materialen.Add(mat); } zoekerRepo.Insert(zoeker); }
换句话说,当必须添加新广告(Zoeker)时,我将检查数据库中是否已存在该材料.如果材料不存在,则materialenRepo.GetByName(string)方法返回null.如果是这样,请将新材质插入数据库并返回Materiaal对象.之后或者如果materialenRepo.GetByName(string)没有返回null,请将该材料添加到广告的Materialen属性并将其插入数据库.
要将数据库与我的应用程序连接,我使用Entity Framework.
我的问题
system.invalidOperationException
: An entity object cannot be referenced by multiple instances ofIEntityChangeTracker
.06002
当zoekerRepo.Insert(zoeker)时,在标记的行上抛出异常;叫做.
我的代码
服务
public class ZoekService { public int InsertZoeker(Zoeker zoeker,ApplicationUser user,string materialenString) { return InsertZoeker(zoeker,user,materialenString.Split(',')); } public int InsertZoeker(Zoeker zoeker,string[] materialen) { zoeker.Gebruiker = user; zoeker.Materialen = new List<Materiaal>(); using (ApplicationDbContext ctx = new ApplicationDbContext()) { ZoekerRepository zoekerRepo = new ZoekerRepository(ctx); MateriaalRepository materiaalRepo = new MateriaalRepository(ctx); // ^^^^ See update one foreach (string m in materialen) { Materiaal materiaal = materiaalRepo.GetByNaam(m); if (materiaal == null) { materiaal = materiaalRepo.Insert(new Materiaal(m)); // ^ See update three } zoeker.Materialen.Add(materiaal); } zoekerRepo.Insert(zoeker); zoekerRepo.SaveChanges(); // <-- Pointer didn't come on this line. return zoeker.ID; } } }
库
ZoekerRepository扩展了GenericRepository< Zoeker>
public class ZoekerRepository : GenericRepository<Zoeker> { public ZoekerRepository() { } public ZoekerRepository(ApplicationDbContext ctx): base(ctx) { } // Some other methods I've add or will override. }
MateriaalRepository扩展了GenericRepository< Materiaal>
public class MateriaalRepository : GenericRepository<Materiaal> { public MateriaalRepository() { } public MateriaalRepository(ApplicationDbContext ctx): base(ctx) { } public Materiaal GetByNaam(string naam) { return (from m in dbSet where m.Naam.Equals(naam) select m).SingleOrDefault<Materiaal>(); } // Some other methods I've add or will override. }
GenericRepository< TEntity>
public class GenericRepo<TEntity> where TEntity : class { internal ApplicationDbContext context; internal DbSet<TEntity> dbSet; public GenericRepo() { context = new ApplicationDbContext(); dbSet = context.Set<TEntity>(); } public GenericRepo(ApplicationDbContext context) { this.context = context; this.dbSet = context.Set<TEntity>(); } public virtual TEntity Insert(TEntity entity) { return dbSet.Add(entity); // <-- after `zoekerRepo.Insert(Zoeker)` the exception // will be thrown on this line. } public void SaveChanges() { try { context.SaveChanges(); } catch (Exception ex) { Console.WriteLine(ex.Message); } } }
我做了什么
当然我已经尝试了其他代码,但所有代码都给出了相同的异常.我将创建我的代码,以便材料的存储库使用名为GenericRepo< TEntity>的相同通用类与广告存储库中的存储库分隔. (除了我要添加或覆盖的东西).我将尽可能多地重用它.一次用于GenericRepo< Zoeker>和GenericRepo< Materiaal>的另一个时间.
我的问题
我怎么能解决这个bug?
更新一个
这个问题与entity object cannot be referenced by multiple instances of IEntityChangeTracker. while adding related objects to entity in Entity Framework 4.1不重复,因为我使用相同的上下文,如接受的答案说:
You can fix this by creating a context outside of the service classes and injecting and using it in both services:
06007
更新两个
控制器
public class DeelController : Controller { private UserManager<ApplicationUser> UserManager { get; set; } private ZoekService _zoekservice = new ZoekService(); public DeelController() { this.UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(ApplicationDbContext)); } [HttpGet] [Authorize] public ActionResult Nieuw() { return View(new Zoeker()); } [HttpPost] [Authorize] [ValidateAntiForgeryToken] public async Task<ActionResult> Nieuw(Zoeker zoeker) { _zoekservice.InsertZoeker(zoeker,await UserManager.FindByNameAsync(User.Identity.Name),zoeker.MaterialenString); return RedirectToAction(nameof(Index)); } }
类
Zoeker扩展了Post
public class Zoeker: Post { public virtual ICollection<Materiaal> Materialen { get; set; } public virtual ICollection<ApplicationUser> Delers { get; set; } [NotMapped] public string MaterialenString { get; set; } // <-- contains a comma separated // list of all materials }
岗位
public class Post { [Key] public int ID { get; set; } public string Titel { get; set; } public string Omschrijving { get; set; } public virtual ApplicationUser Gebruiker { get; set; } public string GebruikerID { get; set; } public DateTime StartPeriode { get; set; } public DateTime? Verwijderd { get; private set; } public DateTime? Opgelost { get; private set; } public DateTime? Belangerijk { get; private set; } public virtual ICollection<Antwoord> Antwoorden { get; set; } }
更新三
我也尝试使用此代码替换上面代码中的注释行,但没有解决此错误:
materiaal = /*materiaalRepo.Insert(*/ new Materiaal(m); //);
如果我使用不存在的材料,使用更新三的代码,我再次遇到了这个错误.
更新四
如果我使用观察者,我会看到:
Material [0]得到了一个字段_entityWrapper类型的EntityWrapperWithoutRelationships< System.Data.Entity.DynamicProxies.Materiaal_E0DDEFDA63D33C75C64324662B40FDC414EC19CA4AD6BF18443B63FC60015374>.注意:此材料已存在于数据库中.在这里我也有同样的错误.
更新五
我也取代了`InsertZoeker(Zoeker
public int InsertZoeker(Zoeker zoeker,string[] materialen) { Zoeker newZoeker = new Zoeker() { Gebruiker = user,StartPeriode = DateTime.Now,Materialen = new List<Materiaal>(),Titel = zoeker.Titel,Omschrijving = zoeker.Omschrijving }; using (ApplicationDbContext ctx = new ApplicationDbContext()) { ZoekerRepository zoekerRepo = new ZoekerRepository(ctx); MateriaalRepository materiaalRepo = new MateriaalRepository(ctx); foreach (string m in materialen) { Materiaal materiaal = materiaalRepo.GetMateriaalByNaam(m); if (materiaal == null) { materiaal = /*materiaalRepo.Insert(*/ new Materiaal(m); //); } newZoeker.Materialen.Add(materiaal); } zoekerRepo.Insert(newZoeker); zoekerRepo.SaveChanges(); return zoeker.ID; } }
解决方法
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。