我有一个客户和销售表
CUSTOMER
--------------
Id (int auto increment)
Name
SALES
---------------
Id (int auto increment)
CustomerId (int)
OrderTotal (decimal)
有了Guid我就可以做到这一点。
dbTransaction = dbContext.Database.BeginTransaction(isolationLevel);
var customer = new Customer()
{
Id = Guid.NewGuid(),
Name = "John Doe"
};
var sales = new Sales()
{
Id = Guid.NewGuid(),
CustomerId = customer.Id,
OrderTotal = 500
};
dbContext.SaveChanges();
dbTransaction.Commit();
如果我的主键是 int (带有 DatabaseGenerateOption.Identity),我该如何执行此操作?
你不能。进入的IDIDENTITY
列是由数据库在插入时生成的,所有规避该列并自行确定 ID 的“技巧”可能都有缺陷。
简短回答:如果您希望在保存之前对生成 ID 有发言权,请使用 GUID (UNIQUEIDENTIFIER
), or a SEQUENCE
(如果您使用的是 SQL Server 2012 或更高版本)。
为什么你不应该自己计算下一个免费 ID:
甚至不要考虑运行诸如context.Customers.Max(c => c.Id) + 1
作为一个可行的解决方案,因为您总是有可能进行并发数据库访问:在您读取下一个“空闲”ID 之后但在存储实体之前,另一个进程或线程可能会将新实体持久保存到同一个表中。计算下一个空闲 ID 很容易发生冲突,除非获取 ID、用它做某事以及使用该 ID 存储实体的整个操作都是原子的。这可能需要数据库中的表锁,这可能效率低下。
(即使使用时也存在同样的问题SEQUENCE
s,SQL Server 2012 中引入的新功能。) (我错了 https://stackoverflow.com/questions/29740705/is-it-possible-to-get-identity-field-value-before-saving-it-in-entity-framework/29740773?noredirect=1#comment47615961_29740773;见答案末尾。)
可能的解决方案:
如果您需要在保存对象之前确定该对象的 ID,则不要使用出现在IDENTITY
柱子。保留 GUID,因为你极不可能与这些发生任何碰撞。
-
无需二选一or另一个:你实际上可以鱼与熊掌兼得!没有什么可以阻止你拥有两个 ID 列,一个由您在外部确定(GUID),另一个由数据库内部确定(GUID)IDENTITY
柱子);请参阅博客文章“CQS 与服务器生成的 ID” http://blog.ploeh.dk/2014/08/11/cqs-versus-server-generated-ids/作者:Mark Seemann,更详细地了解了这个想法。以下是示例的总体思路:
CREATE TABLE Foos
(
FooId INT IDENTITY NOT NULL PRIMARY KEY CLUSTERED,
-- ^^^^^ assigned by the DBMS upon insertion. Mostly for DB-internal use.
Id UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE DEFAULT (NEWID()),
-- ^^ can be dictated and seen by the users of your DB. Mostly for DB-external use.
…
);
CREATE TABLE FooBars
(
FooId INT NOT NULL FOREIGN KEY REFERENCES Foos (FooId),
-- use DB-internal ID in foreign key constraints ^^^^^
…
);
CREATE VIEW PublicFoos AS
SELECT Id, … FROM Foos;
-- ^^ publish the public ID for users of your DB
(确保遵守一些约定,以一致地命名内部和公共 ID 字段名称。)
-
SEQUENCE
s是 SQL Server 2012 中引入的一项功能,是替代IDENTITY
柱子。它们会自动增加,并且在使用以下方式获取下一个免费 ID 时,您将得到一个唯一的编号:NEXT VALUE FOR SomeSequence https://technet.microsoft.com/en-us/library/ff878370.aspx。用例之一MSDN 上提到过 https://msdn.microsoft.com/de-ch/library/ff878058.aspx are:
在以下场景中使用序列而不是标识列: [...] 应用程序在插入表之前需要一个数字。
一些注意事项:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)