Сохраните изменения обратно в базу данных, используя структуру объекта - PullRequest
4 голосов
/ 28 ноября 2011

У меня есть простой запрос, который загружает данные из двух таблиц в графический интерфейс. Я сохраняю загруженные данные в широко доступный объект 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;
   }
}

Итак, если бы я хотел:

1) Сохранить изменения, сделанные пользователем, как мне это сделать? Должен ли я что-то подготовить на стороне базы данных? Как мне справиться с изменением нескольких таблиц (некоторые данные идут сюда, некоторые там)? Мой текущий код, кажется, пишет .KlienciHaslo просто отлично, но это никак не влияет на Подмиоты. Я пробовал разные комбинации, но не повезло.

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

Как мне достичь обоих?

Изменить для ответа (ничего не сохраняет):

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

Ответы [ 2 ]

5 голосов
/ 28 ноября 2011

Видимо ApplyCurrentValues ​​ работает только со скалярными свойствами.

Если вы прикрепите currentClient, то связанные объекты также должны прикрепиться, что означает, что они будут обновлены, когда вы SaveChanges()

Но вы получите исключение Object with the key exists, поскольку вы уже загружаете объект из базы данных в переменную objectInDB.Контекст может содержать только одну копию сущности, и он знает, что currentClient совпадает с objectInDB, поэтому выдает исключение.

Вместо этого попробуйте этот шаблон

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

илиесли вы используете идентификатор в качестве идентификатора, то

// 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
}
1 голос
/ 29 ноября 2011

После некоторой работы и помощи от Кирка по поводу ошибки ObjectStateManager, которую я получил, мне удалось это исправить. Этот код позволяет мне сохранить оба изменения в обеих таблицах.

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