Asp.net mvc 3 EF 4.3.1代码优先更新相关表格 更新:
这让我快发疯了 经过大量的谷歌搜索等,我真的没有接近一个解决方案 然而,我发现了一件让我更加困惑的事情——在m_dbContext.SaveChanges()调用之前实体的“状态”。(请参阅下面的完整存储库代码) 为什么“oldPage”被分离 现在变得非常绝望!!;) 原件: 我似乎在EF代码首次正确更新相关表时遇到问题 在这个简化的示例中,“UpdateInfo”表正在使用新的日期时间进行OK更新。。。。但未使用新的“名称”值更新“页面”表 我正在通过DropCreateDatabaseAlways/override种子设定代码优先POCO。。。EF正在正确地创建测试表-因此在这一点上它似乎知道它在做什么 我确信这是我遗漏的简单/明显的东西 非常感谢大家的帮助 我的班级定义: 我的存储库代码:Asp.net mvc 3 EF 4.3.1代码优先更新相关表格 更新:,asp.net-mvc-3,entity-framework,entity-framework-4,entity-framework-4.1,Asp.net Mvc 3,Entity Framework,Entity Framework 4,Entity Framework 4.1,这让我快发疯了 经过大量的谷歌搜索等,我真的没有接近一个解决方案 然而,我发现了一件让我更加困惑的事情——在m_dbContext.SaveChanges()调用之前实体的“状态”。(请参阅下面的完整存储库代码) 为什么“oldPage”被分离 现在变得非常绝望!!;) 原件: 我似乎在EF代码首次正确更新相关表时遇到问题 在这个简化的示例中,“UpdateInfo”表正在使用新的日期时间进行OK更新。。。。但未使用新的“名称”值更新“页面”表 我正在通过DropCreateDatabaseAl
publicpageget(int-id)
{
Page Page=m_dbContext.Pages.Single(p=>p.Id==Id);
返回页面;
}
公共无效更新(PagePostModel模型)
{
Page oldPage=Get(model.PageModel.Id);//在oldPage Name=“Hello”,DateUpdated=“去年”
Page newPage=Mapper.Map(model.PageModel);//在newPage Name=“再见”(AutoMapper)上
newPage.UpdateInfo=oldPage.UpdateInfo;//复制旧的UpdateInfo,因为它不包含在模型中
newPage.UpdateInfo.DateUpdated=DateTime.UtcNow;//更新到现在
oldPage=newPage;//复制我们从上面的dbContext抓取的更新页面(注意,这里一切看起来都很好..oldPage与预期一样)
m_dbContext.SaveChanges();//更新-仅更新“UpdateInfo”表-未更改“Pages”表:(((
}
正如您所知,实体框架中有一个变更跟踪api
为了跟踪从数据库检索到的实体的更改,DbContext使用其引用值
上面的“更新”函数将新页插入到旧页中。因此,DbContext永远不知道旧页是新页。因此,它是“分离的”
然而,对于UpdateInfo,它是oldPage中引用的副本,所以DbContext可以跟踪该引用的更改,所以它被“修改”
要解决这个问题,使用下面的代码怎么样
Page newPage = Mapper.Map<PageModel, Page>(model.PageModel);
oldPage.UpdateInfo = newPage.UpdateInfo;
oldPage.UpdateInfo.DateUpdated = DateTime.UtcNow;
m_dbContext.SaveChanges();
Page newPage=Mapper.Map(model.PageModel);
oldPage.UpdateInfo=newPage.UpdateInfo;
oldPage.UpdateInfo.DateUpdated=DateTime.UtcNow;
m_dbContext.SaveChanges();
更新
然后,使用附加和分离方法
这些方法帮助您从DbContext附加和分离实体
Page newPage = Mapper.Map<PageModel, Page>(model.PageModel);
// if you attach first, there will be an exception,
// because there is two entities having same id.
m_dbContext.Entry(oldPage).State = EntityState.Detached;
m_dbContext.Pages.Attach(newPage);
// if you don't set IsModified = true,
// DbContext cannot know it is changed.
m_dbContext.Entry(newPage).State = EntityState.Modified;
m_dbContext.SaveChanges();
Page newPage=Mapper.Map(model.PageModel);
//如果先附加,则会出现异常,
//因为有两个实体具有相同的id。
m_dbContext.Entry(oldPage).State=EntityState.Detached;
m_dbContext.Pages.Attach(newPage);
//如果不将IsModified设置为true,
//DbContext无法知道它已更改。
m_dbContext.Entry(newPage).State=EntityState.Modified;
m_dbContext.SaveChanges();
非常感谢您的及时回复-我尝试了该主题的各种变体…但是如何在没有赋值的情况下将“newPage”的内容转换为“oldpage”?非常受欢迎的示例代码只是更新“DateUpdated”值,而不是用户通过传递的模型所做的更改。谢谢!。它现在正在工作!请参阅“Detach”方法已被弃用,因此我不得不改用m_dc.Entry(oldPage).State=EntityState.Detached;再次-感谢您的帮助..非常感谢!感谢您提供的信息。我不知道DbContext中没有分离。我更新了答案
Pages Table
===========
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](max) NULL,
[UpdateInfo_Id] [int] NULL,
UpdateInfo Table
================
[Id] [int] IDENTITY(1,1) NOT NULL,
[DateUpdated] [datetime] NOT NULL,
public Page Get(int id)
{
Page page = m_dbContext.Pages.Single(p => p.Id == id);
return page;
}
public void Update(PagePostModel model)
{
Page oldPage = Get(model.PageModel.Id); // on oldPage Name = "Hello", DateUpdated = "Last Year"
Page newPage = Mapper.Map<PageModel, Page>(model.PageModel); // on newPage Name = "Goodbye" (AutoMapper)
newPage.UpdateInfo = oldPage.UpdateInfo; // take a copy of the old UpdateInfo since its not contained in the model
newPage.UpdateInfo.DateUpdated = DateTime.UtcNow; // update to now
oldPage = newPage; // copy the updated page we grabbed from dbContext above (NB Everything looks great here..oldPage is as expected)
m_dbContext.SaveChanges(); // update - only the 'UpdateInfo' table is being updated - No change to 'Pages' table :(((
}
Page newPage = Mapper.Map<PageModel, Page>(model.PageModel);
oldPage.UpdateInfo = newPage.UpdateInfo;
oldPage.UpdateInfo.DateUpdated = DateTime.UtcNow;
m_dbContext.SaveChanges();
Page newPage = Mapper.Map<PageModel, Page>(model.PageModel);
// if you attach first, there will be an exception,
// because there is two entities having same id.
m_dbContext.Entry(oldPage).State = EntityState.Detached;
m_dbContext.Pages.Attach(newPage);
// if you don't set IsModified = true,
// DbContext cannot know it is changed.
m_dbContext.Entry(newPage).State = EntityState.Modified;
m_dbContext.SaveChanges();