简体   繁体   中英

Save changes back to database using entity framework

I have simple query that loads data from two tables into GUI. I'm saving loaded data to widely available object 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? 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. I tried different combinations but no luck.

2) Add new client to database (and save information to related tables as well)?

    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.

If you attach the currentClient then associated objects should also attach, which means they'll be updated when you 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. The context can only contain one copy of a Entity, and it knows that currentClient is the same as objectInDB so throws an exception.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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