Я создал веб-приложение MVC и должен генерировать уникальный последовательный серийный номер по типу приложения и году, когда пользователи отправляют форму.
Серийный номер будет сохранен в таблице базы данных MyAppCodeSEQ истолбец "AppCode" является PK MyAppCodeSEQ.
Это мой код ниже:
public MyAppCodeSEQ GenNewAppCode(string appType)
{
MyAppCodeSEQ model = null;
try
{
var today = DateTime.Now;
int maxSeq = _db.MyAppCodeSEQ.Where(x => x.AppType == appType && x.Year == today.Year).Select(x => x.SEQ).DefaultIfEmpty(0).Max();
maxSeq = maxSeq + 1;
var appCode = "XX" + appType + today.Year % 1000 + string.Format("{0:000000}", maxSeq);
model = new MyAppCodeSEQ()
{
AppCode = appCode,
AppType = appType,
Year = today.Year,
SEQ = maxSeq,
};
_db.MyAppCodeSEQ.Add(model);
_db.SaveChanges();
}
catch(Exception e)
{
Thread.Sleep(100);
GenNewAppCode(appType);
}
return model;
}
Функция будет вызываться при вставке дублированного ключа.Тем не менее, ошибка ниже возникала снова и снова.
System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
---> System.Data.Entity.Core.UpdateException: An error occurred while updating the entries. See the inner exception for details.
---> System.Data.SqlClient.SqlException: Violation of PRIMARY KEY constraint 'PK_AppCodeSEQ'.
Cannot insert duplicate key in object 'dbo.MyAppCodeSEQ'. The duplicate key value is (XXYY18002193).
The statement has been terminated.
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
System.Data.SqlClient.SqlDataReader.get_MetaData()
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption)
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary`2 identifierValues, List`1 generatedValues)
System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
System.Data.Entity.Internal.InternalContext.SaveChanges()
Есть ли лучшее решение для создания серийного номера?