gpt4 book ai didi

c# - 如何使用 SQL Server 和 Entity Framework 模拟序列(来自 Oracle)的使用

转载 作者:太空宇宙 更新时间:2023-11-03 14:05:51 24 4
gpt4 key购买 nike

我们一直喜欢在 Oracle 数据库中使用序列,以便在整个数据库中创建全局唯一的主键 ID。这么多,我们将在使用 SQL Server 数据库时模仿同样的事情:

CREATE TABLE MainSequence(
Id int IDENTITY(1,1) CONSTRAINT pkMainSequence PRIMARY KEY
)

我正在尝试切换到 Entity Framework,这对我来说非常陌生。创建一个我可以用来快速获取下一个可用的全局唯一 Id 的扩展方法似乎很简单。

public static int GetNextId( this Entities db ) {
var ms = new MainSequence();
db.MainSequences.AddObject( ms );
db.SaveChanges( SaveOptions.None );
return ms.Id;
}

因为它是一个标识列,我所要做的就是向数据库添加一个新对象并保存更改,以便使用真实值更新 Id 属性。这很好用。但是我在尝试将它用于与外键相关的表时似乎遇到了麻烦:

var dataId = db.GetNextId();
db.Datas.AddObject( Data.CreateData( dataId, someValueForThisColumn );
db.Caches.AddObject(
Cache.CreateCache( db.GetNextId(),
DatabaseMethods.GetOrAddLocation( source.GetLocationText() ),
DateTime.Now,
dataId ) );

缓存表有数据表的外键。在此之后立即调用 SaveChanges(); 时,会生成异常。

System.Data.SqlClient.SqlException: Violation of PRIMARY KEY constraint 'pkData'. Cannot insert duplicate key in object 'dbo.Data'. The duplicate key value is (78162). The statement has been terminated.

由于某种原因,新数据行似乎尝试两次插入数据库,但我不确定为什么会这样。我已经确认每次运行代码时,都会返回一个不同的 MainSequence ID。似乎每当获得新 ID 时调用 db.SaveChanges 就是问题所在,但没有其他方法可以用真正的 int 填充,我也没有看看为什么会出现问题。我做错了什么?

最佳答案

我的问题是行 db.SaveChanges( SaveOptions.None );。我使用此选项的原因是为了避免 SaveOptions.AcceptAllChangesAfterSave,在我看来,通过从其他 StackOverflow 问题(无效或被误解)收集的信息,我认为这会为我提供一种基本的数据库事务形式。我确实多次阅读了 MSDN 文档:

After changes are saved, the AcceptAllChangesAfterSave() method is called, which resets change tracking in the ObjectStateManager.

对我来说,这听起来很糟糕,就像事务更改跟踪一样。我认为如果在保存调用中不接受更改,则数据库“事务”将在出现错误的情况下回滚(我后来发现情况并非如此)。相反,所有这一切只是让 ObjectContext 仍然认为更改未保存。因此,在下一次保存调用时,将重新应用“未保存”的更改。 Ta-da,主键异常。这也解释了为什么我的主序列会跳过值。

关于c# - 如何使用 SQL Server 和 Entity Framework 模拟序列(来自 Oracle)的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9350816/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com