简体   繁体   English

实体框架:使用新的父对象更新现有的子对象

[英]Entity Framework : Updating an existing child object with a new parent object

I am trying to do a data load using EF and stuck where I can't insert a new record when the child record is existing. 我正在尝试使用EF进行数据加载,并且卡在存在子记录时无法插入新记录的位置。 Here is an example. 这是一个例子。

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; }
}

In the above example multiple Applications can belong to one Position . 在上面的示例中,多个应用程序可以属于一个Position Assume we already have the Position record and if I make the following call, it will fail because Position with ID 5 is already in the database. 假设我们已经有位置记录,并且如果我进行以下调用,它将失败,因为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);
        }
    }

Now I can pull that record and make a call like this and get it to work 现在,我可以提取该记录并进行这样的呼叫并使其正常工作

     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);
        }
    }

However I want to know if there is an easy way to do this. 但是我想知道是否有一种简单的方法可以做到这一点。 I am converting JSON to objects and saving for data loading purpose. 我将JSON转换为对象并保存以用于数据加载。

All I want is if the child record exists (in this case Position ), then just update it with the new values. 我想要的就是子记录是否存在(在本例中为Position ),然后使用新值对其进行更新。 An Upsert 热门

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

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

The above example where I am using AddOrUpdate will do the Upsert for the parent object but not the child object. 上面使用AddOrUpdate的示例将为父对象而不是子对象执行Upsert。 I want the child object also to be updated. 我希望子对象也被更新。

Thanks 谢谢

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  
};

Is this what you are looking for? 这是你想要的? Do an update of ApplicationPosotion without hitting the database for Position of the given id (here 5)? 是否在不访问数据库中给定id(此处为5)的Position的情况下更新ApplicationPosotion

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();

The above works. 以上作品。 Here is my modified code. 这是我修改的代码。

                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);

How ever is their a simple setting in EF that tells just do an Upsert ? 他们在EF中的简单设置如何告诉Upsert? Right now every object I have to break it down. 现在,我必须分解每个对象。

Here is an example of 3 level deep 这是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);

But I love to skip this step 但我喜欢跳过这一步

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

Because I do not want to set this up for every object. 因为我不想为每个对象设置它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM