Vb.net 将实体与子实体一起保存

Vb.net 将实体与子实体一起保存,vb.net,entity-framework,Vb.net,Entity Framework,我已经为此挣扎了几天,我需要一些帮助。 我也在谷歌和StackOverFlow上做了很多搜索,但没有找到解决方案 我正在努力,我相信,这是一件简单的事情,但我不能让我去工作 使用EntityFramework,我正在更改名为“tblAnneeFinanciere”的表中的一条记录,同时我还在is NavigationProperty的“tblAnneeFinanciere.tblperioDefinitianceere”中添加子记录。但是我无法使用SaveChanges上下文方法来保存所有信息

我已经为此挣扎了几天,我需要一些帮助。 我也在谷歌和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。但希望找到一种方法来防止不必要的数据库访问。