Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 尝试插入父对象的实体框架_C#_Entity Framework - Fatal编程技术网

C# 尝试插入父对象的实体框架

C# 尝试插入父对象的实体框架,c#,entity-framework,C#,Entity Framework,问题 我正在使用实体框架向数据库中添加一个复杂的对象模型。我遇到了一个问题,我试图插入一个子对象,EF也试图插入父对象,这导致了数据库中的完整性问题 解释 在我的示例中,假设我们有两个表: 商店 商店业绩 一个店铺可以有许多ShopPerformance条目,ShopPerformance必须有一个店铺,并且店铺记录已经存在于数据库中(因此EF应该将其放在一边,关注ShopPerformance) 在我的示例中,我仅尝试添加ShopPerformance(在本例中,ShopPerformance

问题

我正在使用实体框架向数据库中添加一个复杂的对象模型。我遇到了一个问题,我试图插入一个子对象,EF也试图插入父对象,这导致了数据库中的完整性问题

解释

在我的示例中,假设我们有两个表:

  • 商店
  • 商店业绩
  • 一个店铺可以有许多ShopPerformance条目,ShopPerformance必须有一个店铺,并且店铺记录已经存在于数据库中(因此EF应该将其放在一边,关注ShopPerformance)

    在我的示例中,我仅尝试添加ShopPerformance(在本例中,ShopPerformance的实例称为“performance”:

    当我调用SaveChanges()时,EF也试图插入商店,这会在数据库中导致约束错误,因为它具有防止重复条目的约束(基于商店名称)

    我尝试过的事情

    我已尝试将ShopPerformance中的Shop属性设置为null,以阻止EF做我不想做的事情(它仍然将ShopID作为单独的属性)。首先,我尝试:

    Shop theShop = performance.Shop;
    performance.Shop = null;
    this.db.Entry(performance).State = System.Data.EntityState.Added;
    this.db.SaveChanges();
    performance.Shop = theShop;
    
    在这种情况下,EF以某种方式重新建立了车间和性能之间的联系,并尝试再次插入车间

    然后我试着:

    Shop theShop = performance.Shop;
    this.db.Entry(performance).Entity.Shop = null;
    this.db.Entry(performance).State = System.Data.EntityState.Added;
    this.db.SaveChanges();
    this.db.Entry(performance).Entity.Shop = theShop;
    
    这会导致空引用异常

    所需分辨率

    我正在寻找一种方法来插入我的性能对象,而不用EF在商店里摆弄。这完全破坏了我现在的工作

    TL;DR

    我希望实体框架只插入/更新我告诉它的对象,而不插入/更新任何相关对象。我如何才能做到这一点?

    您尝试过:

    var shop = this.db.shops.Find(id);
    shop.Performances.Add(new Performance());
    
    this.db.SaveChanges();
    


    您正在处理断开连接的对象,
    performance
    performance.Shop
    都是EF未跟踪的实体,EF不知道
    performance.Shop
    的状态

    将新的
    性能
    与现有的
    性能.商店
    一起添加时,EF不知道
    性能.商店
    是一个现有实体,EF也会将图中所有未跟踪的对象标记为
    已添加

    发生这种情况的原因是,当您使用DbSet.Add方法时 是,Screencasts.Add),而不仅仅是根实体的状态被标记 “补充道,”但图表中的所有内容都与上下文无关 先前知道的也被添加了标记。-

    你需要做的是

    • 如果您有外键关联,您可以只分配id而不是引用

      performance.ShopId = performance.Shop.Id;
      performance.Shop = null;
      this.db.Entry(performance).State = System.Data.EntityState.Added;
      this.db.SaveChanges();
      
    • 或者,您需要先将
      performance.Shop
      附加到上下文中(status=
      Unchanged
      ),让EF知道它是一个现有实体

      this.db.Entry(performance.Shop).State = EntityState.Unchanged;
      this.db.Entry(performance).State = EntityState.Added;
      this.db.SaveChanges();
      

    你能再显示一点代码吗?我特别想看看
    性能的来源以及它的
    商店属性是如何添加的。嗨,Anthony。代码是长度,但作为解释,我在一个平面文件中解析。然后我查找商店的名称(这是唯一的)。如果它不存在,我将插入它,否则我将不处理它。然后我尝试插入性能。我在分析平面文件时创建并填充EF对象。这足够信息吗?嗨,Pavel。我尝试创建一个新的性能对象并跨现有对象的属性进行复制(除了对商店对象的引用),但这仍然不起作用。谢谢。我将在星期一试一试。
    
    performance.ShopId = performance.Shop.Id;
    performance.Shop = null;
    this.db.Entry(performance).State = System.Data.EntityState.Added;
    this.db.SaveChanges();
    
    this.db.Entry(performance.Shop).State = EntityState.Unchanged;
    this.db.Entry(performance).State = EntityState.Added;
    this.db.SaveChanges();