实体框架不会更新外键对象 [英] Entity Framework does not update Foreign Key object

查看:84
本文介绍了实体框架不会更新外键对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的实体框架和这种行为混淆了我:

  [表(ClinicProfile)] 
公共类ClinicProfile
{
[关键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)
公众诠释标识{搞定;组; }

[ForeignKey的(联络资料)]
公众诠释ContactDataId {搞定;组; }
公共联络资料联络资料{搞定;组; }
}

表(联络资料)]
公共类联络资料
{
[关键]
[DatabaseGenerated(DatabaseGeneratedOption。身份)
公众诠释标识{搞定;组; }


}

当插入新实体一切工作正常 - 联络资料保存到表并指定外键:

  clinicProfile.ContactData =联络资料; 
SharedContext.Current.Entry(clinicProfile).STATE = EntityState.Added;
SharedContext.Current.SaveChanges();



但是,当我尝试更新这个实体,联络资料没有得到更新。



  clinicProfile.ContactData =联络资料; 
SharedContext.Current.Entry(clinicProfile).STATE = EntityState.Modified;
SharedContext.Current.SaveChanges();



我必须标记为修改的联络资料吗? ?还是我做错了什么。



修改 - 2 - 答案



使用此代码,如果联络人资料为DB中的新对象,新对象ID。

  clinicProfile.ContactData =联络资料; 
SharedContext.Current.Entry(clinicProfile).STATE = EntityState.Modified;
SharedContext.Current.SaveChanges();

如果你只是想更新旧的联络资料,这将是正确使用此代码:

  SharedContext.Current.Entry(联络资料).STATE = EntityState.Modified; 
SharedContext.Current.SaveChanges();

修改 - 扩展代码的快照


$从MVC控制器,回发从页。b $ b

代码。参数clinicProfile和联络资料,adressData包含有效标识的。

  [HttpPost] 
[ValidateAntiForgeryToken]
公众的ActionResult修改(ClinicProfile clinicProfile,联络资料联络资料,AdressData adressData)
{
ViewBag.Id = clinicProfile.Id;

如果(ModelState.IsValid)
{
如果(clinicProfile.Id!= 0)
{
clinicProfile.ContactData =联络资料;
clinicProfile.AdressData = adressData;
clinicProfile.AdressDataComposed = adressData.ComposeData();
clinicProfile.ContactDataComposed = contactData.ComposeData();

SharedContext.Current.Entry(clinicProfile).STATE = EntityState.Modified;
SharedContext.Current.SaveChanges();

Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload,clinicProfile.Id);
Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload,clinicProfile.Id);

返回查看(新ClinicProfileComposite {AdressData = adressData,ClinicProfile = clinicProfile,联络资料=联络资料});
}

{
clinicProfile.ContactData =联络资料;
clinicProfile.AdressData = adressData;
clinicProfile.AdressDataComposed = adressData.ComposeData();
clinicProfile.ContactDataComposed = contactData.ComposeData();

SharedContext.Current.Entry(clinicProfile).STATE = EntityState.Added;
SharedContext.Current.SaveChanges();

Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload,clinicProfile.Id);
Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload,clinicProfile.Id);

返回RedirectToAction(信息,新{ID = clinicProfile.Id});
}
}

ViewBag.Id = clinicProfile.Id;
返回查看(新ClinicProfileComposite {AdressData = adressData,ClinicProfile = clinicProfile,联络资料=联络资料});
}


解决方案

您刚刚放错位置的外键财产

  [表(ClinicProfile)] 
公共类ClinicProfile
{
[键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)
公众诠释标识{搞定;组; }

// [ForeignKey的(联络资料)]这里错了地方
公众诠释ContactDataId {搞定;组; }
[ForeignKey的(ContactDataId)] //这里的正确位置
公共联络资料联络资料{搞定;组; }
}

表(联络资料)]
公共类联络资料
{
[关键]
[DatabaseGenerated(DatabaseGeneratedOption。身份)
公众诠释标识{搞定;组; }


}

和当你想设置外键的数据,您可以设置ContactDataId值或从数据库作为对象检索联络资料,并将其设置在ClinicProfile

  //根据发布的数据后

[HttpPost]
[ValidateAntiForgeryToken]
公众的ActionResult修改(ClinicProfile clinicProfile,联络资料联络资料,adressData adressData)
{
ViewBag.Id = clinicProfile.Id;

如果(ModelState.IsValid)
{
如果(clinicProfile.Id!= 0)//这里要告诉SharedContext
{
到联络资料附加到clinicProfile
//你需要从分贝
VAR检索联络资料的lastVersion currentContactData = SharedContext.Current.ContactData.Single(T => t.Id = contactData.Id) ;
//更新的currentContactData
clinicProfile.ContactData = currentContactData更改后的数据; //而不是联络资料;
clinicProfile.AdressData = adressData;
clinicProfile.AdressDataComposed = adressData.ComposeData();
clinicProfile.ContactDataComposed = contactData.ComposeData();

SharedContext.Current.Entry(clinicProfile).STATE = EntityState.Modified;
SharedContext.Current.SaveChanges();

Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload,clinicProfile.Id);
Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload,clinicProfile.Id);

返回查看(新ClinicProfileComposite {AdressData = adressData,ClinicProfile = clinicProfile,联络资料=联络资料});
}

{
clinicProfile.ContactData =联络资料;
clinicProfile.AdressData = adressData;
clinicProfile.AdressDataComposed = adressData.ComposeData();
clinicProfile.ContactDataComposed = contactData.ComposeData();

SharedContext.Current.Entry(clinicProfile).STATE = EntityState.Added;
SharedContext.Current.SaveChanges();

Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload,clinicProfile.Id);
Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload,clinicProfile.Id);

返回RedirectToAction(信息,新{ID = clinicProfile.Id});
}
}

ViewBag.Id = clinicProfile.Id;
返回查看(新ClinicProfileComposite {AdressData = adressData,ClinicProfile = clinicProfile,联络资料=联络资料});
}



//为注释讨论的结果。



如果您想更新联络资料,你需要告诉联络资料是由它的状态设置为修改和你在过去的文章中提到,如果你把下面这将工作修改背景:



SharedContext.Current.Entry(clinicProfile).STATE = EntityState.Modified; SharedContext.Current.Entry(联络资料).STATE = EntityState.Modified; SharedContext.Current.SaveChanges();



希望这会帮助你。


I'm new to Entity Framework and this behavior confuses me:

    [Table("ClinicProfile")]
    public class ClinicProfile
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [ForeignKey("ContactData")]
        public int ContactDataId { get; set; }
        public ContactData ContactData { get; set; }
    }

    [Table("ContactData")]
    public class ContactData
    {
         [Key]
         [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
         public int Id { get; set; }

         ...
    }

When inserting the new entity all works fine - ContactData is saved to the table and foreign key assigned:

clinicProfile.ContactData = contactData;
SharedContext.Current.Entry(clinicProfile).State = EntityState.Added;
SharedContext.Current.SaveChanges();

But when I try to update this entity, ContactData don't get an update.

clinicProfile.ContactData = contactData;
SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified;
SharedContext.Current.SaveChanges();

Must I mark ContactData as modified too? Or am I just doing something wrong?

EDIT-2 - The answer

Use this code, if contactData is the new object in the DB, with the new object id.

clinicProfile.ContactData = contactData;
SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified;
SharedContext.Current.SaveChanges();

If you just want to update the old contactData, it would be correct to use this code:

SharedContext.Current.Entry(contactData).State = EntityState.Modified;
SharedContext.Current.SaveChanges();

EDIT - extended code snapshot

Code from MVC controller, postback from the page. Parameters "clinicProfile" and "contactData", "adressData" contain valid Id's.

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Modify(ClinicProfile clinicProfile, ContactData contactData, AdressData adressData)
        {
            ViewBag.Id = clinicProfile.Id;

            if (ModelState.IsValid)
            {
                if (clinicProfile.Id != 0)
                {
                    clinicProfile.ContactData = contactData;
                    clinicProfile.AdressData = adressData;
                    clinicProfile.AdressDataComposed = adressData.ComposeData();
                    clinicProfile.ContactDataComposed = contactData.ComposeData();

                    SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified;
                    SharedContext.Current.SaveChanges();

                    Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);
                    Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);

                    return View(new ClinicProfileComposite { AdressData = adressData, ClinicProfile = clinicProfile, ContactData = contactData });
                }

                {
                    clinicProfile.ContactData = contactData;
                    clinicProfile.AdressData = adressData;
                    clinicProfile.AdressDataComposed = adressData.ComposeData();
                    clinicProfile.ContactDataComposed = contactData.ComposeData();

                    SharedContext.Current.Entry(clinicProfile).State = EntityState.Added;
                    SharedContext.Current.SaveChanges();

                    Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);
                    Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);

                    return RedirectToAction("Info", new { id = clinicProfile.Id });
                }
            }

            ViewBag.Id = clinicProfile.Id;
            return View(new ClinicProfileComposite { AdressData = adressData, ClinicProfile = clinicProfile, ContactData = contactData });
        }

解决方案

you just misplaced the foreign key property

 [Table("ClinicProfile")]
    public class ClinicProfile
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        //[ForeignKey("ContactData")] here the wrong place
        public int ContactDataId { get; set; }
        [ForeignKey("ContactDataId")] // here the correct place
        public ContactData ContactData { get; set; }
    }

    [Table("ContactData")]
    public class ContactData
    {
         [Key]
         [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
         public int Id { get; set; }

         ...
    }

and when you want to set the foreign key data, you can either set the ContactDataId value or retrieve the ContactData from Database as object and set it in the ClinicProfile

// according to your data posted later

[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Modify(ClinicProfile clinicProfile, ContactData contactData, AdressData adressData)
        {
            ViewBag.Id = clinicProfile.Id;

            if (ModelState.IsValid)
            {
                if (clinicProfile.Id != 0)
                {
                    // here you want to tell the SharedContext to attach the contactData to the clinicProfile 
                    // you need to retrieve the lastVersion of contactData from db
                    var currentContactData=SharedContext.Current.ContactData.Single(t=>t.Id=contactData.Id);
                    // update the changed data in the currentContactData
                    clinicProfile.ContactData =currentContactData;  // instead of contactData;
                    clinicProfile.AdressData = adressData;
                    clinicProfile.AdressDataComposed = adressData.ComposeData();
                    clinicProfile.ContactDataComposed = contactData.ComposeData();

                    SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified;
                    SharedContext.Current.SaveChanges();

                    Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);
                    Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);

                    return View(new ClinicProfileComposite { AdressData = adressData, ClinicProfile = clinicProfile, ContactData = contactData });
                }

                {
                    clinicProfile.ContactData = contactData;
                    clinicProfile.AdressData = adressData;
                    clinicProfile.AdressDataComposed = adressData.ComposeData();
                    clinicProfile.ContactDataComposed = contactData.ComposeData();

                    SharedContext.Current.Entry(clinicProfile).State = EntityState.Added;
                    SharedContext.Current.SaveChanges();

                    Config.SaveClinicPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);
                    Config.SaveClinicPreviewPhoto(clinicProfile.ClinicImageUpload, clinicProfile.Id);

                    return RedirectToAction("Info", new { id = clinicProfile.Id });
                }
            }

            ViewBag.Id = clinicProfile.Id;
            return View(new ClinicProfileComposite { AdressData = adressData, ClinicProfile = clinicProfile, ContactData = contactData });
        }

// as result of comments discussion

if you want to update contactData , you need to tell the context that contactData was modified by setting its state to modified and as you mentioned in your last post, it will work if you make the following:

SharedContext.Current.Entry(clinicProfile).State = EntityState.Modified; SharedContext.Current.Entry(contactData).State = EntityState.Modified; SharedContext.Current.SaveChanges();

hope that this will help you

这篇关于实体框架不会更新外键对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆