2016-11-14 64 views
0

我想使用EF做一个数据加载并卡住当儿童记录存在时无法插入新记录的地方。这是一个例子。实体框架:用新的父对象更新现有的子对象

public class Position 
{ 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public long Id { get; set; } 
    public string PositionName { get; set; } 
} 

public class Application 
{ 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public long Id { get; set; } 
    public string ApplicationName { get; set; } 
    public Position ApplicationPosotion { get; set; } 
} 

在上述例子中的多个应用程序可以属于一个位置。假设我们已经有职位记录,并且如果我拨打以下电话,它将失败,因为ID为5的位置已经在数据库中。

public static void UseEntityFrameWorkOneFail() 
    { 
     using (var db = new DemoDbContext(@"Server=DESKTOP-HUJVOQ5\SQLEXPRESS;Database=Demo2;Trusted_Connection=True;")) 
     { 
      Application appOne = new Application 
      { 
       Id = 7, 
       ApplicationName = "AppOne", 
       ApplicationPosotion = new Position { Id = 5, PositionName = "ABC" } 
      }; 

      db.Applications.Add(appOne); 
      db.SaveChanges(); 

      appOne = db.Applications.Find(7); 
      Console.WriteLine(appOne.ApplicationPosotion.PositionName); 
     } 
    } 

现在我可以拉这个纪录,让这样的电话,得到它的工作

 public static void UseEntityFrameWorkPass() 
    { 
     using (var db = new DemoDbContext(@"Server=DESKTOP-HUJVOQ5\SQLEXPRESS;Database=Demo2;Trusted_Connection=True;")) 
     { 
      Application appOne = new Application 
      { 
       Id = 8, 
       ApplicationName = "AppOne", 
       ApplicationPosotion = db.Positions.Find(5) 
      }; 

      db.Applications.Add(appOne); 
      db.SaveChanges(); 

      appOne = db.Applications.Find(8); 
      Console.WriteLine(appOne.ApplicationPosotion.PositionName); 
     } 
    } 

但是我想知道如果有一个简单的方法来做到这一点。我将JSON转换为对象并保存用于数据加载目的。

我只想要的是如果子记录存在(在这种情况下位置),那么只需使用新值更新它。 一个的Upsert

  Application appOne = new Application 
      { 
       Id = 7, 
       ApplicationName = "AppOne", 
       ApplicationPosotion = new Position { Id = 5, PositionName = "123" } 
      }; 

      db.Applications.AddOrUpdate(appOne); 
      db.SaveChanges(); 

在那里我使用AddOrUpdate会做的Upsert父对象,但不是孩子的对象上面的例子。我希望子对象也被更新。

感谢

回答

1
var appPosotion = db.Positions.Any(o => o.Id== 5)) ?? new Position { Id = 5, PositionName = "ABC" } 

Application appOne = new Application 
{ 
    Id = 8, 
    ApplicationName = "AppOne", 
    ApplicationPosotion = appPosotion 
}; 
+0

以上仍然强迫我做检查。我正在寻找一种方法来覆盖子对象具有的任何值。更喜欢Upsert –

+0

是不是'db.Positions.FirstOrDefault(o => o.Id == 5))??''而不是'.Any('? – Developer

0

这是你在找什么?更新ApplicationPosotion而不击中给定ID(这里是5)的Position的数据库?

var position = new Position { Id = 5}; 
db.Positions.Attach(position); 

      Application appOne = new Application 
      { 
       Id = 8, 
       ApplicationName = "AppOne", 
       ApplicationPosotion = position 
      }; 

      db.Applications.Add(appOne); 
      db.SaveChanges(); 
0

上述工作。这是我修改后的代码。

   Application appOne = new Application 
      { 
       Id = 7, 
       ApplicationName = "AppOne", 
       ApplicationPosotion = new Position { Id = 5, PositionName = "123" } 
      }; 

      db.Positions.AddOrUpdate(appOne.ApplicationPosotion); 
      db.Applications.AddOrUpdate(appOne); 
      db.SaveChanges(); 

      appOne = db.Applications.Find(7); 
      Console.WriteLine(appOne.ApplicationPosotion.PositionName); 

他们在EF中的简单设置是什么,它告诉我们只要做一个Upsert?现在我必须将每个对象都分解。

+0

你没有看到我的答案。我已经提出了: ) – CodeNotFound

+0

你的回答是正确的。我期待看看我们是否有我们可以设置的选项,这样我就不必破坏每一个复杂的对象。我正在尝试执行一个ETL,让我获取需要加载到SQL Server中的不同类型的对象 –

0

这里是3级深

   Application appOne = new Application 
      { 
       Id = 7, 
       ApplicationName = "AppOne", 
       ApplicationPosition = new Position 
       { 
        Id = 5, 
        PositionName = "123", 
        SalaryAmount = new Salary() { Id = 1, SalaryAmount = 200000 } 
       } 
      }; 

      db.Salarys.AddOrUpdate(appOne.ApplicationPosition.SalaryAmount); 
      db.Positions.AddOrUpdate(appOne.ApplicationPosition); 
      db.Applications.AddOrUpdate(appOne); 
      db.SaveChanges(); 

      appOne = db.Applications.Find(7); 
      Console.WriteLine(appOne.ApplicationPosition.SalaryAmount.SalaryAmount); 

一个例子,但我喜欢跳过这一步

  db.Salarys.AddOrUpdate(appOne.ApplicationPosition.SalaryAmount); 
      db.Positions.AddOrUpdate(appOne.ApplicationPosition); 

因为我不想设置此为每个对象。