简体   繁体   English

使用实体框架将更改保存回数据库

[英]Save changes back to database using entity framework

I have simple query that loads data from two tables into GUI. 我有简单的查询,将两个表中的数据加载到GUI中。 I'm saving loaded data to widely available object Clients currentlySelectedClient . 我将加载的数据保存到广泛可用的对象Clients currentlySelectedClient

using (var context = new EntityBazaCRM()) 
{
   currentlySelectedClient = context.Kliencis.Include("Podmioty").FirstOrDefault(d => d.KlienciID == klientId);
   if (currentlySelectedClient != null) 
   {
      textImie.Text = currentlySelectedClient.Podmioty.PodmiotOsobaImie;
      textNazwisko.Text = currentlySelectedClient.Podmioty.PodmiotOsobaNazwisko;
   } 
   else 
   {
      textNazwa.Text = currentlySelectedClient.Podmioty.PodmiotFirmaNazwa;
   }
}

So now if I would like to: 所以现在如果我想:

1) Save changes made by user how do I do it? 1)保存用户所做的更改我该怎么做? Will I have to prepare something on database side? 我是否必须在数据库方面准备一些东西? How do I handle modifying multiple tables (some data goes here, some there)? 如何处理修改多个表(某些数据在这里,有些数据在那里)? My current code seems to write .KlienciHaslo just fine, but it doesn't affect Podmioty at all. 我现在的代码好像写了.KlienciHaslo就好了,但它根本不影响Podmioty。 I tried different combinations but no luck. 我尝试了不同的组合,但没有运气。

2) Add new client to database (and save information to related tables as well)? 2)将新客户端添加到数据库(并将信息保存到相关表)?

    currentClient.Podmioty.PodmiotOsobaImie = textImie.Text;  // not saved
    currentClient.Podmioty.PodmiotOsobaNazwisko = textNazwisko.Text; // not saved
    currentClient.KlienciHaslo = "TEST111"; // saved

    using (var context = new EntityBazaCRM()) 
    {
        var objectInDB = context.Kliencis.SingleOrDefault(t => t.KlienciID == currentClient.KlienciID);
        if (objectInDB != null) 
        {
           // context.ObjectStateManager.ChangeObjectState(currentClient.Podmioty, EntityState.Modified);
           //context.Podmioties.Attach(currentClient.Podmioty);
           context.Kliencis.ApplyCurrentValues(currentClient); // update current client
           //context.ApplyCurrentValues("Podmioty", currentClient.Podmioty); // update current client
        } 
        else 
        {
           context.Kliencis.AddObject(currentClient);  // save new Client
        }
        context.SaveChanges();
     }

How can I achieve both? 我如何实现这两个目标?

Edit for an answer (doesn't save anything ): 编辑答案(不保存任何内容):

currentClient.Podmioty.PodmiotOsobaImie = textImie.Text; // no save
currentClient.Podmioty.PodmiotOsobaNazwisko = textNazwisko.Text; // no save
currentClient.KlienciHaslo = "TEST1134"; // no save

using (var context = new EntityBazaCRM()) 
{
    if (context.Kliencis.Any(t => t.KlienciID == currentClient.KlienciID)) 
    {
        context.Kliencis.Attach(currentClient); // update current client
    } 
    else 
    {
        context.Kliencis.AddObject(currentClient);  // save new Client
    }
    context.SaveChanges();
}            

Apparently ApplyCurrentValues only works with scalar properties. 显然, ApplyCurrentValues仅适用于标量属性。

If you attach the currentClient then associated objects should also attach, which means they'll be updated when you SaveChanges() 如果你附加currentClient那么关联的对象也应该附加,这意味着当你SaveChanges()时它们会被更新

But you'll get an Object with the key exists exception because you are already loading the object from the database into the objectInDB variable. 但是,您将获得一个Object with the key exists异常的Object with the key exists因为您已经将对象从数据库加载到objectInDB变量中。 The context can only contain one copy of a Entity, and it knows that currentClient is the same as objectInDB so throws an exception. 上下文只能包含一个Entity的副本,并且它知道currentClientobjectInDB相同,因此抛出异常。

Try this pattern instead 请尝试使用此模式

if (context.Kliencis.Any(t => t.KlienciID == currentClient.KlienciID)) 
{
    context.Kliencis.Attach(currentClient); // update current client
} 
else 
{
    context.Kliencis.AddObject(currentClient);  // save new Client
}

or if you're using an identity as the ID, then 或者,如果您使用身份作为ID,那么

// if the ID is != 0 then it's an existing database record
if (currentClient.KlienciID != 0) 
{
    context.Kliencis.Attach(currentClient); // update current client
} 
else // the ID is 0; it's a new record
{
    context.Kliencis.AddObject(currentClient);  // save new Client
}

After some work and help from Kirk about the ObjectStateManager error that I was getting I managed to fix this. 经过Kirk的一些工作和帮助,我得到了关于ObjectStateManager的错误,我设法解决了这个问题。 This code allows me to save both changes to both tables. 此代码允许我将两个更改保存到两个表。

 currentClient.Podmioty.PodmiotOsobaImie = textImie.Text;
 currentClient.Podmioty.PodmiotOsobaNazwisko = textNazwisko.Text;
 currentClient.KlienciHaslo = "TEST1134";
 using (var context = new EntityBazaCRM()) {
       if (context.Kliencis.Any(t => t.KlienciID == currentClient.KlienciID)) {
           context.Podmioties.Attach(currentClient.Podmioty);
           context.Kliencis.Attach(currentClient);
           context.ObjectStateManager.ChangeObjectState(currentClient.Podmioty, EntityState.Modified);
           context.ObjectStateManager.ChangeObjectState(currentClient, EntityState.Modified);
        } else {
           context.Kliencis.AddObject(currentClient);  // save new Client
        }
        context.SaveChanges();
  }

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

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