SaveChanges()不会使用更新的数据修改现有数据库记录

问题描述 投票:0回答:1

我试图通过调用_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后,记录仍未更新。

当我调试代码时,我可以看到结果上的IntValue属性在每次检索时都有我输入的第一个值(4),因此看起来好像dbContext保留在结果对象上。它只是没有用修改后的值更新我的数据库。我的数据库也是一个远程数据库,它不在我的本地计算机上托管。我无法找到任何可能存在问题的内容。

任何帮助,将不胜感激。

c# sql entity-framework
1个回答
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; }
}

然后你会遇到这样一种情况:有两种方法可以在新的IntAttribute实例中指向EntityAttribute,还有一些鸡蛋和鸡蛋情景。如果记录的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指向名为“MyInt”的引用属性,其中包含名为MyInts的实体DbSet。在您的实体中为ID(PK和FK)采用适当的命名约定将使您的代码更容易理解。

注意我将FirstOrDefault改为Single。使用Linq,使用最严格的预期操作。如果您希望行可用或不可用,则仅使用“OrDefault”,并且正在处理它们不可用的情况。如果您期望1行,请使用“单个”而不是“第一个”。 “第一”表示我期待很多,但只关心第一个,它应该总是包括一个OrderBy条款。这是为了避免潜在的错误(更新错误的记录,最后是NullReference Exceptions等)

现在,如果您确定没有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”,则rank为“5”,test返回为“4”,然后奇怪的是肯定会发生。如果test返回为“5”,那么此时的数据库也应报告“5”,并且可能还有其他东西正在重置该值。使用SaveChanges之后的“test =”行上的断点,使用手动查询检查数据库。如果查询无法在启用该断点的情况下运行,则另一个嫌疑人将是您在打开的事务中运行,并且在此调用之后未提交事务。打开事务将阻止查询执行,直到Tx范围完成。对于事务,默认操作是回滚任何更改,如果它没有被告知提交。如果它没有锁定并且DB显示“4”但是test显示“5”那么我会仔细观察以确保你使用Single而不是FirstOrDefault,因为这看起来像你查询一条记录的错误在数据库中,但EF正在选择另一个。 (即你期望有1条记录,但有多条符合标准。)在这种情况下使用Single会引发一个异常,即预期有1条记录,但多条返回。

© www.soinside.com 2019 - 2024. All rights reserved.