c# – 如何将两个不同的对象插入数据库,但检查它们是否已经存在
情况草图
我开发了一个系统,其中可以将许多材料(代码为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. 我的问题 当我在下面的标题上使用代码时,我有这个例外:
当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不重复,因为我使用相同的上下文,如接受的答案说:
请参阅上面代码的评论. 更新两个 在这里,我已经完成了我的代码的新部分. 控制器 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; } } 解决方法
愚蠢的我,我正在使用其他上下文让我的DeelController内的用户.我在我的问题中删除了该代码.
@mwwills:这确实是一个重复的问题. @everyone_else:对不起,我已经做到了. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |