我试图通过调用_dbContext.SaveChanges()来更新SQL数据库中的现有记录,但是它没有使用我修改的新值来更新记录。
我尝试了所有其他解决方案,但都没有用。
我的代码如下:
public int UpdateRank(Guid localId, int rank, Guid entityTypeId)
{
var result = _dbContext.EntityAttribute.FirstOrDefault(en => en.ParentGuid == localId && en.EntityAttributeTypeId == entityTypeId);
result.IntValue = rank;
return _dbContext.SaveChanges();
}
找到一些解决方案后,我还尝试添加
_dbContext.Entry(result).State = EntityState.Modified;
以及
_dbContext.EntityAttribute.Attach(result);
在_dbContext.SaveChanges()之前无效。
如果我从_dbContext.SaveChanges()之前的这些代码片段中获取任何先前的代码序列,则代码将运行并且不会引发错误,但不会更新记录。如果我添加
_dbContext.EntityAttribute.Update(result);
然后调用SaveChanges,出现以下错误: SqlException:无法更新标识列“ ID”。
ID是数据库生成的bigint。我都加了
_dbContext.EntityAttribute.Update(result).Property(en => en.Id).IsModified = false;
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
分别访问我的数据访问项目中的UpdateRank方法和EntityAttribute数据库文件,它们使代码运行没有错误,但是在调用SaveChanges之后仍未更新记录。
当我调试代码时,我可以看到result上的IntValue属性每次检索时都输入我输入的第一个值(4),因此它看起来好像dbContext保留了结果对象。只是没有用修改后的值更新我的数据库。我的数据库也是一个远程数据库,它不在我的本地计算机上托管。我找不到任何说明可能是问题的东西。
任何帮助将不胜感激。
答案 0 :(得分:0)
您可能需要为问题添加更多详细信息,包括EntityAttribute
的实体定义和/或EF实体类型配置,包括任何要映射的属性。是否将“ IntValue”作为FK映射到另一个实体?这是导致您看不到更新的最可能原因。
例如,如果EntityAttribute看起来像这样:
public class EntityAttribute
{
// ... properties, key, etc.
public int IntValue { get; set; }
[ForeignKey("IntValue")]
public virtual IntAttribute MyInt { get; set; }
}
然后您遇到一种情况,有两种方法可以将EntityAttribute指向一个新的IntAttribute实例,以及一些麻烦的解决方案。如果记录开始的IntValue为4且ID为4的MyInt,则暗示将其更改为“ 5”是因为将IntValue设置为5或将MyInt设置为ID = 5的实体。第二种选择是正确的您已经定义了FK列:
public int UpdateRank(Guid localId, int rank, Guid entityTypeId)
{
var result = _dbContext.EntityAttribute.Single(en => en.ParentGuid == localId
&& en.EntityAttributeTypeId == entityTypeId);
var myInt = _dbContext.MyInts.Single(x => x.MyIntId == rank);
result.MyInt = myInt;
return _dbContext.SaveChanges();
}
这是假设FK指向带有名为MyInts的实体DbSet的引用属性“ MyInt”。在您的实体中为ID(PK和FK)采用正确的命名约定将大大有助于使您的代码更易于理解。
请注意,我将FirstOrDefault
更改为Single
。对于Linq,请使用限制性最高的预期操作。仅当您预期行应该可用或不可用并且正在处理不可用的情况时,才使用“ OrDefault”。如果期望1行,请使用“单”而不是“第一”。 “第一”表示我期望有很多,但只关心第一个,它应始终包含OrderBy
子句。这是为了避免潜在的错误(更新错误的记录,以NullReference异常结束等)
现在,如果您确定没有FK参考,请尝试以下操作:
public int UpdateRank(Guid localId, int rank, Guid entityTypeId)
{
var result = _dbContext.EntityAttribute.Single(en => en.ParentGuid == localId
&& en.EntityAttributeTypeId == entityTypeId);
result.IntValue = rank;
return _dbContext.SaveChanges();
var test = result.IntValue;
}
在var test = ...
行上放置一个断点。
返回到test
的值是什么?如果原始IntValue为“ 4”,等级为“ 5”,并且test
返回为“ 4”,那么肯定会出现奇怪的情况。如果test
返回为“ 5”,则此时的数据库也应报告“ 5”,可能是其他原因正在重置该值。在SaveChanges之后的“ test =“行上使用断点,使用手动查询检查数据库。如果查询无法在启用该断点的情况下运行,则另一个怀疑可能是您正在一个打开的事务中运行,并且在此调用之后未提交该事务。一个打开的事务将阻止查询执行,直到Tx作用域完成。对于事务,默认操作是在未告知要提交的情况下回滚所有更改。如果它没有锁定,并且数据库显示“ 4”,但是test
显示“ 5”,那么我会仔细检查以确保您使用的是Single
而不是FirstOrDefault
,因为看起来像一个错误,您正在查询数据库中的一条记录,但是EF选择了另一条记录。 (即,您期望有1条记录,但是有多个符合条件的记录。)在这种情况下,使用Single
会引发异常,结果是期望有1条记录,但返回了多条记录。