Vb.net 将实体与子实体一起保存
我已经为此挣扎了几天,我需要一些帮助。 我也在谷歌和StackOverFlow上做了很多搜索,但没有找到解决方案 我正在努力,我相信,这是一件简单的事情,但我不能让我去工作 使用EntityFramework,我正在更改名为“tblAnneeFinanciere”的表中的一条记录,同时我还在is NavigationProperty的“tblAnneeFinanciere.tblperioDefinitianceere”中添加子记录。但是我无法使用SaveChanges上下文方法来保存所有信息 我尝试了一些不同的场景,只是为了得出不同的错误 这里是我的代码片段Vb.net 将实体与子实体一起保存,vb.net,entity-framework,Vb.net,Entity Framework,我已经为此挣扎了几天,我需要一些帮助。 我也在谷歌和StackOverFlow上做了很多搜索,但没有找到解决方案 我正在努力,我相信,这是一件简单的事情,但我不能让我去工作 使用EntityFramework,我正在更改名为“tblAnneeFinanciere”的表中的一条记录,同时我还在is NavigationProperty的“tblAnneeFinanciere.tblperioDefinitianceere”中添加子记录。但是我无法使用SaveChanges上下文方法来保存所有信息
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
- 我的第一次尝试是将更改的实体分配给链接到上下文的引用,实体被正确保存,但不是“tblAnneeFinanciere.tblperionedefinanciere”中的子记录
- 在第二次尝试中 我使用ApplyCurrentValues调用传入要保存的信息,但引发了一个异常 在ObjectStateManager中找不到键与所提供对象的键匹配的对象。验证所提供对象的键值是否与必须应用更改的对象的键值匹配。 请注意,我没有同时运行每次尝试,每次尝试都是单独运行的
- 在第三次尝试中,女巫与第一次有点相似 请正确保存主表“tblAnneeFinanciere”,但当实体添加到“TBLPerioDefinitanciere”时,会引发异常,告诉我ObjectContext实例已被释放,不能再用于需要连接的操作。
视窗7;Visual Studio 2013;目标框架版本:4.0;EntityFramework版本:4.1在多层应用程序中使用EF时,实体将从通常跟踪其更改的上下文中删除 也就是说,如果您使用上下文,修改属性并向其添加子项,则上下文会跟踪这些更改,并且
SaveChanges
知道该做什么
但是,当您有一个多层应用程序时,实体将从上下文中删除
您需要做的是自己跟踪更改。然后,您必须实例化一个新上下文,将实体附加到上下文,并设置附加实体及其所有子实体的状态
可以执行两种不同的操作将entty附加到上下文:
- 使用
将实体添加到其集合中会将所有实体的状态设置为Add()
,保存更改会将它们视为新的Added
- 使用
附加实体。在这种情况下,您需要设置实体的状态,以便保存更改知道要做什么Attach()
ctx.Set<TEntity>().Add(newEntity);
ctx.SaveChanges();
var attached = ctx.Set<TEntity>().Attach(changedEntity);
ctx.Entry(attached).State = EntityState.Modified;
ctx.SaveChanges();
ctx.Set().Add(newEntity);
ctx.SaveChanges();
这将附加整个树,就像添加了所有对象一样
修改断开连接的实体的示例:
ctx.Set<TEntity>().Add(newEntity);
ctx.SaveChanges();
var attached = ctx.Set<TEntity>().Attach(changedEntity);
ctx.Entry(attached).State = EntityState.Modified;
ctx.SaveChanges();
var attached=ctx.Set().Attach(变更属性);
ctx.Entry(附件).State=EntityState.Modified;
ctx.SaveChanges();
这将附加整个树,就好像所有对象都没有变化一样
请记住,您需要跟踪更改,并在将对象附加到上下文后将其设置回原位。我不明白为什么要连接到数据库两次。连接到数据库->更改记录并在数据库上下文上保存更改。因此,更改和保存发生在Using块内部。我正在使用此代码段中的数据库连接来模拟Web服务层/多层设计感谢我所期待的,根据您的建议,我已经成功地完成了这项工作。但现在我想知道如何区分插入的条目和修改的条目。因此,可以构建一个通用方法来保存/更新记录。当然,我可以在数据库中查找PrimaryKey。但希望找到一种方法来防止不必要的数据库访问。