Reputation: 2185
I'm struggling with this for a couple days now and I need a little help. I also do many searches over Google and StackOverFlow, but did not find a solution.
I'm trying, what I believe, is something simple but I can't get i to work.
Using EntityFramework I'm changing a record from a table named "tblAnneeFinanciere", and also I'm adding child record in "tblAnneeFinanciere.tblPeriodeFinanciere" from is NavigationPropoerty. But I can't get the SaveChanges context method to save all information.
I've try some different scenario, just to reach different error.
Here my code snippet
Public Sub Test()
Dim AnneesFine = New List(Of tblAnneeFinanciere)
Using database = Informat.WPF.EF.MaitreDBEntities.GetEFConnections()
Dim query = From data In database.tblAnneeFinanciere
Where data.ID = 7
Select data
AnneesFine = query.ToList
End Using
Dim ChangedAnneeFina = AnneesFine.First
ChangedAnneeFina.Descr = Date.Now.ToLongDateString
ChangedAnneeFina.Poincon = Date.Now
Dim addedRecord = New tblPeriodeFinanciere() With {
.ID = 1,
.Descr = "Test#1",
.DescrEn = "Test#1",
.NoPeriode = 10,
.pCieID = ChangedAnneeFina.CieID.Value,
.DateDebut = Date.Now,
.DateFin = Date.Now,
.pAnneeFinanciereID = ChangedAnneeFina.ID,
.Poincon = Date.Now
}
ChangedAnneeFina.tblPeriodeFinanciere.Add(addedRecord)
Using database = Informat.WPF.EF.MaitreDBEntities.GetEFConnections()
''*************************************************************
''First attempt
Dim obj = database.GetObjectByKey(ChangedAnneeFina.EntityKey)
obj = ChangedAnneeFina
''*************************************************************
'Second attempt
database.tblAnneeFinanciere.ApplyCurrentValues(ChangedAnneeFina) ' Value are correctly applied
database.SaveChanges() '' Saving tblAnneeFinanciere work correctly but child table 'tblPeriodeFinanciere' is not updated
'*************************************************************
'third attempt
' database.tblAnneeFinanciere.ApplyCurrentValues(ChangedAnneeFina) ' Value are correctly applyed
Dim obj2 = database.GetObjectByKey(ChangedAnneeFina.EntityKey)
obj2 = ChangedAnneeFina
database.tblPeriodeFinanciere.AddObject(ChangedAnneeFina.tblPeriodeFinanciere.First)
'*************************************************************
database.SaveChanges()
End Using
End Sub
My first attempt, witch is assigning the changed Entity to the reference linked to the context, the entity is saved correctly, but not the child record from "tblAnneeFinanciere.tblPeriodeFinanciere".
In the second attempt I'm using the ApplyCurrentValues call to transfer in information to save, but a exception raise An object with a key that matches the key of the supplied object could not be found in the ObjectStateManager. Verify that the key values of the supplied object match the key values of the object to which changes must be applied. Note that I've not run each attempt at the same time, each attempt were run separately.
In the third attempt witch is a bit similar to the first Do save the main table "tblAnneeFinanciere" correctly, but when the the entity is added to "tblPeriodeFinanciere", a exception is raised telling me The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
What I do wrong, which way should I go?
My working environment is
Windows 7; Visual Studio 2013; Target framework version : 4.0; EntityFramework version : 4.1
Upvotes: 0
Views: 267
Reputation: 39025
When you're using EF in a multilayered application, the Entity is taken out of the context that usually tracks its changes.
I.e. if you're withing a context, and modify a property, and add children to it, the context tracks this changes, and SaveChanges
knows what to do.
But, when you have a multilayered app, the entity is taken out of the context.
What you need to do is track the changes yourself. And, then you have to instance a new context, attach the entity to the context, and set the state of the attached entity and all their children.
You can do two diferent things to attach the entty to the context:
Add()
will set the state of all entites to Added
,and save changes will treat them all as if they were newAttach()
. In this case you need to set the state of the entity so that save changes knows what to do.Example of adding a disconected entity:
ctx.Set<TEntity>().Add(newEntity);
ctx.SaveChanges();
This would attach the whole tree as if all the objects were Added
Example of modifying a disconnected entity:
var attached = ctx.Set<TEntity>().Attach(changedEntity);
ctx.Entry(attached).State = EntityState.Modified;
ctx.SaveChanges();
This would attach the whole tree as if all the objects were Unchanged
Remember that you need to track the changes, and set them back after attaching the objects to the context.
Upvotes: 1