C# 无法更新实体框架模型
我已经花了将近七个小时来解决这个问题,但却找不到解决办法。我来了,和你们分享这个问题 请注意,下面的示例是我原始项目的简化和子集。我尽量为你简化它 首先,我有两种商业模式: 以下EDMX图如下所示: 我使用的是MVC 4,我有一个简单的页面,您可以在其中分别输入主客场球队名称,并有一个保存按钮来保存这些球队和比赛: CSHTML 正如您在控制器内部看到的,输入的团队名称将与数据库中的团队名称进行比较。如果存在,则将对其进行更新;否则插入。插入没有问题,但当在文本框中输入现有团队名称时,我会收到以下错误消息: 无法将值NULL插入表的“UpdateDate”列中 “测试数据库团队”;列不允许空值。插入失败。这个 声明已终止 我得到这个错误,即使在控制器内部,我显式地为需要更新的记录设置UpdateDate,并将其状态设置为Modified。但是,错误消息显示好像未设置UpdateDate字段。我已调试并确保字段已正确更新,但在SQL Profiler中未设置UpdateDate。我很困惑 如果需要,我可以分享完整的源代码 更新我怀疑它与附加/分离有关,但我不确定 更新2我简化了代码,看看它是否有效,它是否有效。那么为什么原始代码不起作用呢C# 无法更新实体框架模型,c#,entity-framework,asp.net-mvc-4,ef-database-first,C#,Entity Framework,Asp.net Mvc 4,Ef Database First,我已经花了将近七个小时来解决这个问题,但却找不到解决办法。我来了,和你们分享这个问题 请注意,下面的示例是我原始项目的简化和子集。我尽量为你简化它 首先,我有两种商业模式: 以下EDMX图如下所示: 我使用的是MVC 4,我有一个简单的页面,您可以在其中分别输入主客场球队名称,并有一个保存按钮来保存这些球队和比赛: CSHTML 正如您在控制器内部看到的,输入的团队名称将与数据库中的团队名称进行比较。如果存在,则将对其进行更新;否则插入。插入没有问题,但当在文本框中输入现有团队名称时,我会收到以
Team homeTeam = new Team() { TeamId = 1 };
Team awayTeam = new Team() { TeamId = 2 };
_dbContext.Teams.Attach(homeTeam);
homeTeam.UpdatedDate = DateTime.Now;
_dbContext.Teams.Attach(awayTeam);
awayTeam.UpdatedDate = DateTime.Now;
Match newMatch = new Match()
{
HomeTeam = homeTeam,
AwayTeam = awayTeam,
UpdateDate = DateTime.Now
};
_dbContext.AddToMatches(newMatch);
_dbContext.SaveChanges();
UpdateDate不允许空值。使其成为数据库中可为空的列
此外,在您的EDMX中,如注释中提到的scheien。EF中的模式表明,添加/插入或更新时,不允许输入空值 确保传递的是正确的不可为空的值。
您还可以更改表的架构并更新模型,以便输入null。在此处设置断点:awayTeam.updateDate=DateTime.Now 然后,当您运行它时,您可以判断它是否指向现有团队
我敢肯定,问题是当你试图做一个更新。在这种情况下,您没有分离原始对象,而是尝试重新分配。尝试分离现有的AwayTeam,然后附加matchData.AwayTeam,将其标记为已修改,然后尝试保存。他还应使其在模型中为空,以反映数据库。UpdateDate不是故意为空的字段。已为插入的记录和更新的记录设置了该代码。您已编辑该代码。如果以前的版本不可为空,则会出错。“现在它应该可以正常工作了。”阿玛·杜普兰蒂埃,我忘了提那件事。以前它和现在一样,然后我更改了它以检查它是否可以工作,并且忘记了更改回原始版本。对不起,我误导了你。这样仍然不行。您是否尝试过设置xxx.updateDate=DateTime.Now;在执行_dbContext.ObjectStateManager.ChangeObjectState之后。。。在else中的语句?那么,如果要更新,请重新设置它?试试看它是否能解决你的问题。如果有效,请告诉我,我会发布答案。我可以看看你的模型吗?@Belogix,让我试试,我会尽快回复。@Reddy,我已经提供了模型图。你需要特别的东西吗?@Belogix,不幸的是没有任何更改。我正在传递DateTime。现在它是一个不可为空的值。是的,只有在尝试更新时才会发生此错误,这非常令人沮丧。我将您的解决方案应用于客场和主场球队,现在我得到了这个错误:ObjectStateManager中已经存在具有相同密钥的对象。ObjectStateManager无法跟踪具有相同密钥的多个对象。即使我分离了现有的实体。如需进一步调查,请查看问题更新2部分。
public class MatchController : Controller
{
TestEFEntities _dbContext = new TestEFEntities();
public ActionResult Index()
{
return View();
}
public ActionResult NewMatch()
{
return View();
}
[HttpPost]
public ActionResult NewMatch(Match matchData)
{
try
{
if (ModelState.IsValid)
{
using (TransactionScope ts = new TransactionScope())
{
string homeTeamName = matchData.HomeTeam.TeamName;
Team existingHomeTeam = _dbContext.Teams.SingleOrDefault(i => i.TeamName == homeTeamName);
Team homeTeam = existingHomeTeam ?? matchData.HomeTeam;
homeTeam.UpdatedDate = DateTime.Now;
if (existingHomeTeam == null)
{
_dbContext.AddToTeams(homeTeam);
}
else
{
_dbContext.ObjectStateManager.ChangeObjectState(homeTeam, System.Data.EntityState.Modified);
}
string awayTeamName = matchData.AwayTeam.TeamName;
Team existingAwayTeam = _dbContext.Teams.SingleOrDefault(i => i.TeamName == awayTeamName);
Team awayTeam = existingAwayTeam ?? matchData.AwayTeam;
awayTeam.UpdatedDate = DateTime.Now;
if (existingAwayTeam == null)
{
_dbContext.AddToTeams(awayTeam);
}
else
{
_dbContext.ObjectStateManager.ChangeObjectState(awayTeam, System.Data.EntityState.Modified);
}
matchData.HomeTeam = homeTeam;
matchData.AwayTeam = awayTeam;
_dbContext.AddToMatches(matchData);
_dbContext.SaveChanges();
ts.Complete();
}
ViewBag.Status = "Success";
return PartialView(matchData);
}
else
{
ViewBag.Status = "Invalid input.";
return PartialView(matchData);
}
}
catch (Exception ex)
{
ViewBag.Status = "Error: " + (ex.InnerException != null ? ex.InnerException.Message : ex.Message);
return PartialView(matchData);
}
}
}
Team homeTeam = new Team() { TeamId = 1 };
Team awayTeam = new Team() { TeamId = 2 };
_dbContext.Teams.Attach(homeTeam);
homeTeam.UpdatedDate = DateTime.Now;
_dbContext.Teams.Attach(awayTeam);
awayTeam.UpdatedDate = DateTime.Now;
Match newMatch = new Match()
{
HomeTeam = homeTeam,
AwayTeam = awayTeam,
UpdateDate = DateTime.Now
};
_dbContext.AddToMatches(newMatch);
_dbContext.SaveChanges();