你的关切是有效的——在经常使用的网站上,这种情况很可能发生,解决办法并不容易。 如@Mikecito所述,你可以使用客户栏目<> 准则>代码>,但业绩受到重大打击,我猜测你不想使用。
目前,你这样做的方式非常糟糕,因为唯一的解决办法是把你的代码列入单一的可序列交易——交易必须既包含选择Id,又保留记录。 这将使查阅<代码>InventoryObjects sequential,因为每项选择的最高限额在交易发生之前将锁定整个表格——在交易中没有人能够读到或书写数据。 在很少访问现场时,这并不必然是一个问题,但是在经常访问的现场,它可能是诺琴。 在你目前设立的机构中,没有任何办法可以不同地这样做。
The partial improvement is using separate table to hold max value + stored procedure to get the next value and increment the stored value in atomic operation - (it actually simulates sequences from Oracle). Now the only complication is if you need the sequence without gaps. For example if something goes wrong with saving of new InventoryObject
the selected Id will be lost and it will create a gap in the id s sequence. If you need sequence without gaps you must again use transaction to get the next Id and save the record but this time you will only lock single record in sequence table. Retrieving the Id from sequence table should be as close to saving changes as possible to minimize time when sequence record is locked.
这里是服务器序列表和序列程序的样本:
CREATE TABLE [dbo].[Sequences]
(
[SequenceType] VARCHAR(20) NOT NULL, /* Support for multiple sequences */
[Value] INT NOT NULL
)
CREATE PROCEDURE [dbo].[GetNextSequenceValue]
@SequenceType VARCHAR(20)
AS
BEGIN
DECLARE @Result INT
UPDATE [dbo].[Sequences] WITH (ROWLOCK, UPDLOCK)
SET @Result = Value = Value + 1
WHERE SequenceType = @SequenceType
RETURN @Result
END
表格不需要先用代码绘制,你永远不能直接查阅。 您必须创建海关数据库,以便在电子格式建立一个数据库时,增加表格和储存程序。 https://stackoverflow.com/questions/5701608/unique-key-with-ef-code-first/5701702#5701702>。 您还必须增加具有开端价值的首创记录。
Now you only need to call stored procedure to get a value before you are going to save the record:
// Prepare and insert record here
// Transaction is needed only if you don t want gaps
// This whole can be actually moved to overriden SaveChanges in your context
using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew,
new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }))
{
record.Id = context.Database.ExecuteStoreCommand("dbo.GetNextSequenceValue @SequenceType",
new SqlParameter("SequenceType", "InventoryObjects"));
context.SaveChanges();
}