sql-server - 插入后实体框架更新为错误的值
问题描述
发现此问题是因为我有一个对象,该对象具有根据 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();
}
更新:将调用的方法从静态更改为实例方法,并且仅在进行其他更改后才运行它,而不是在创建后立即运行它似乎已经解决了问题,原因我无法理解。由于我还没有足够大的样本来完全确定问题已得到解决,而且我对真正发生的变化没有任何解释,所以我暂时将这个问题悬而未决。
解决方案
推荐阅读
- ansible - Ansible:剧本范围的角色名称
- flutter - 实现概述文本字段在颤动的下拉菜单中输入带有标签文本
- css - 如何为不同的页面下一个js使用两个不同的全局css?
- vba - VBA 函数第一次正确返回一个值,但在第二次运行时则不正确
- swift - 使用 [UInt8] 的 Alamofire 发布请求
- amazon-web-services - 为 aws ec2 负载均衡器设置 http 基本授权密码
- sql-server - 尽管数据很小,但字符串列的 Power BI 字典大小都超过 1mb
- ios - 设备定向后子视图的中心
- r - R 在安装 gert 时因“捕获非法操作”而崩溃
- python - Matplotlib 图 '.supxlabel' 不起作用