如何实体添加到的DbContext递归关系,同时避免重复补充?

编程入门 行业动态 更新时间:2024-10-24 06:24:31
本文介绍了如何实体添加到的DbContext递归关系,同时避免重复补充?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我使用实体框架4.4和我有一个一对多的关系模型是这样的:

类项目{公共字符串keyPart1 {搞定;组; } 公共字符串keyPart2 {搞定;组; } 公共虚拟集装箱货柜{搞定;组; } 公共字符串ContainerId {搞定;组; } } //想法是,许多项目将被分配到一个容器级集装箱{公共字符串ContainerId {搞定;组; } 私人的ICollection<项目> _items; 公共虚拟的ICollection<项目>由于 { {返回_items? (_items =新的HashSet< A>()); } 保护集合{_items =价值; } } }

现在,这里的的DbContext:

公共类StorageContext:的DbContext {公共DbSet<项目>项目{搞定;组; } 公共DbSet<铲斗和GT;水桶{搞定;组; } 公共覆盖无效OnModelCreating(DbModelBuilder模型构建器) { base.OnModelCreating(模型构建器); modelBuilder.Entity<项目方式>()HasKey(I =>新建{i.keyPart1,i.keyPart2}).HasRequired(I => i.Container); } }

现在,假设我有N个项目实例。每个项属于一个容器,其包含多个项目的情况下,其中每一个属于一个容器,因此模型无休止递归

欲再通过循环我项目实例当前列表以及每个添加到数据库方面:

的foreach(VAR我在LocalItemList) { IDbSetExtensions.AddOrUpdate<项目>(db.Items,I); } dbContext.SaveChanges();

这是我想不通的问题是如何告诉上下文 AddOrUpdate 的集装箱让我不明白的主键重复异常。在某些时候,我们会碰到一个项目具有相同的集装箱作为另一个,但我会得到一个复制了的SaveChanges主键异常()。

如果我添加集装箱到DbSet,是项目增补的设置呢?我怎么能作出这样的 AddOrUpdate 呢?

解决方案

我不相信如果你想插入相关集装箱 s转换数据库随着项目 S,或者如果你只是想创建一个关系到现​​有的集装箱秒。该集装箱实体没有在数据库中,并在你的对象图,你只能有一个集装箱 实例的每个键(多的引用的这些实例允许)不应该在所有的问题,一个简单的代码一样...

的foreach(VAR我在LocalItemList) { dbContext.Items.Add(I) } dbContext.SaveChanges();

...实际上应该无一例外地工作。所以,你可能有以下两种情况之一这可以解释主键约束冲突:

  • 的容器实体已经存在于数据库中,并在你的对象图,你只能有一个集装箱的实例(多重的引用的这些实例再次允许的)。这是最简单的情况下,你可以通过使用解决它:

    的foreach(VAR我在LocalItemList) { dbContext.Containers.Attach(i.Container); dbContext.Items.Add(ⅰ); } dbContext.SaveChanges();

    如果您有多个集装箱实例相同的密钥,这将无法工作,抛出的......具有相同键的对象已存在于ObjectContext的......的(或类似)异常。它也不会工作,如果集装箱•不要在数据库中还不存在(你可能会得到一个违反外键约束的话)。

  • 如果您有多个集装箱对象实例在你的对象图相同的密钥必须通过每一个唯一实例替换重复关键你连接或实体添加到上下文之前。为了使这个过程更简单我会先删除循环引用,然后使用本地收集找出如果一个集装箱使用相同的密钥已经被附:

    的foreach(VAR我在LocalItemList) {我。 Container.Items = NULL; VAR attachedContainer = dbContext.Containers.Local .SingleOrDefault(C => c.ContainerId == i.Container.ContainerId); 如果(attachedContainer!= NULL) i.Container = attachedContainer; ,否则 dbContext.Containers.Attach(i.Container); //或dbContext.Containers.Add(i.Container); //取决于如果要插入容器或没有 dbContext.Items.Add㈠; } dbContext.SaveChanges();

I'm using Entity Framework 4.4 and I have a One-To-Many relationship model like this:

class Item { public string keyPart1 { get; set; } public string keyPart2 { get; set; } public virtual Container container { get; set; } public string ContainerId { get; set; } } // Idea is that many Items will be assigned to a container class Container { public string ContainerId { get; set; } private ICollection<Item> _Items; public virtual ICollection<Item> As { get { return _Items ?? (_Items = new HashSet<A>()); } protected set { _Items = value; } } }

Now, here's the DbContext:

public class StorageContext : DbContext { public DbSet<Item> Items { get; set; } public DbSet<Bucket> Buckets { get; set; } public override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Item>().HasKey( i => new { i.keyPart1, i.keyPart2 } ).HasRequired( i => i.Container ); } }

Now, supposing I have N Item instances. Each Item belongs to a container, which contains multiple item instances, each of which belongs to a container, and so the model recurses endlessly.

I want to then cycle through my current list of Item instances and add each to the db context:

foreach (var i in LocalItemList) { IDbSetExtensions.AddOrUpdate<Item>(db.Items, i); } dbContext.SaveChanges();

The problem that I can't figure out is how to tell the context to AddOrUpdate the Container so that I don't get primary key duplicate exceptions. At some point we'll run into an Item that has the same Container as another, but I'll get a duplicate primary key exception on SaveChanges().

If I Add a Container to the DbSet, are the Items added to the Set as well? How can I make that an AddOrUpdate instead?

解决方案

I am not sure if you want to insert the related Containers into the database along with the Items, or if you only want to create a relationship to already existing Containers. The possible case that the Container entities do not exist in the database and in your object graph you only have one Container instance per key (multiple references to those instances are allowed) should not be a problem at all and a simple code like...

foreach (var i in LocalItemList) { dbContext.Items.Add(i); } dbContext.SaveChanges();

...should actually work without exception. So, you probably have one of the following two situations which would explain the primary key constraint violation:

  • The Container entities already exist in the database and in your object graph you only have one Container instance per key (multiple references to those instances are allowed again). This is the easy case and you can solve it by using:

    foreach (var i in LocalItemList) { dbContext.Containers.Attach(i.Container); dbContext.Items.Add(i); } dbContext.SaveChanges();

    If you have multiple Container instances for the same key this won't work and throw an "...an object with the same key already exists in the ObjectContext..." (or similar) exception. It also won't work if the Containers do not exist yet in the database (you'll probably get a foreign key constraint violation then).

  • If you have multiple Container object instances with the same key in your object graph you must replace the duplicates by one unique instance per key before you attach or add the entities to the context. To make this process simpler I would remove the circular references first and then use the Local collection to figure out if a Container with the same key is already attached:

    foreach (var i in LocalItemList) { i.Container.Items = null; var attachedContainer = dbContext.Containers.Local .SingleOrDefault(c => c.ContainerId == i.Container.ContainerId); if (attachedContainer != null) i.Container = attachedContainer; else dbContext.Containers.Attach(i.Container); // or dbContext.Containers.Add(i.Container); // depending on if you want to insert the Container or not dbContext.Items.Add(i); } dbContext.SaveChanges();

更多推荐

如何实体添加到的DbContext递归关系,同时避免重复补充?

本文发布于:2023-10-30 23:52:15,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1544375.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:递归   实体   关系   DbContext

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!