首页 > 解决方案 > 插入后实体框架更新为错误的值

问题描述

发现此问题是因为我有一个对象,该对象具有根据 ID 计算的字段,其中包含 ID 作为其一部分,带有前缀和校验和数字。要求这些计算值是唯一的,但它们也不能是随机的,所以这似乎是最好的方法。

有问题的代码如下所示:

entity = new Entity() { /* values */ };
context.SaveChanges(); //generate the ID field
entity.CALCULATED_FIELD = CalculateField(prefix, entity.ID);

这在 99% 的情况下都可以正常工作,但有时我们会在数据库中得到如下所示的值:

ID: 1234
CALCULATED_FIELD : prefix000{1233}8
EXPECTED: prefix000{1234}3

大括号中的部分是根据 ID 列计算的。

计算字段不正确的事实已经够糟糕了,但这意味着在执行 savechanges 时,不能保证返回到 Entity Framework 的行是最初处理的行!我正在考虑在插入时使用存储过程来解决生成的字段问题,但从长远来看,如果我们继续处理错误的行,我们将有很多错误的数据。

当我告诉实体框架将表映射到存储过程时,它生成了以下样板代码:

INSERT [dbo].[tableName](fields...)
VALUES(values...)

DECLARE @ID int
SELECT @ID = [ID]
FROM [dbo].[tableName]
WHERE @@ROWCOUNT > 0 AND [ID] = scope_identity()

SELECT t0.[ID]
FROM [dbo].[tableName] as t0
WHERE @@ROWCOUNT > 0 AND t0.[ID] = @ID

我能想到的最好的主意是在调用 scope_identity() 之前可能会发生额外的插入。我们正在迁移这个系统,而不是使用我们使用 @@IDENTITY 的存储过程,那里会有所不同吗?

编辑:计算字段:

    public static string CalculateField(string prefix, int ID)
    {
        var calculated = prefix.PadRight(17 - ID.ToString().Length)
            .Replace(" ", "0") + ID.ToString();
        var multiplier = 3;
        var sum = 0;
        foreach (char c in calculated.ToCharArray().Reverse())
        {
            sum += multiplier * int.Parse(c.ToString());
            multiplier = 4 - multiplier;
        }
        if (sum % 10 == 0) { return calculated + "0"; }
        return calculated + (10 - (sum % 10)).ToString();
    }

更新:将调用的方法从静态更改为实例方法,并且仅在进行其他更改后才运行它,而不是在创建后立即运行它似乎已经解决了问题,原因我无法理解。由于我还没有足够大的样本来完全确定问题已得到解决,而且我对真正发生的变化没有任何解释,所以我暂时将这个问题悬而未决。

标签: sql-serverentity-framework-6

解决方案


推荐阅读