У меня была такая же проблема, но я решил ее в c #.
У меня должен быть объект, сопоставленный с таблицей:
public class MyEntity
{
Kind IdKind{get; set;}
int Number{get;set;}
}
У меня должен быть и вспомогательный объект для хранения последнего числа, использованного для каждого вида.
public class LastNumber
{
Kind IdKind{get;set;}
int LastNumber{get;set;}
}
Тогдаперед добавлением строки (объекта MyEntity) в таблицу я должен рассчитать правильное число, используя поле LastNumber в LastNumberEntity, где Kind равно моему значению Kind.
Мы должны отметить, что в этой стратегии есть проблема параллелизма, посколькудва разных потока могут добавлять объект одного и того же вида одновременно, эти потоки будут проверять один и тот же LastNumberEntity, чтобы получить значение LastNumber.Эта проблема имеет известное решение в сущности.Код может выглядеть следующим образом:
public int GetNumber(Kind idKind)
{
using (var db = new MyDataContext())
{
var lastNumber = db.LastNumbers.Single(x=>x.IdKind == idKind);
for (int attemps = 0; attemps < 10;)
{
try
{
lastNumber.LastNumber++;
db.SaveChanges();
return lastNumber.LastNumber;
}
catch (DbUpdateConcurrencyException ex)
{
attemps++;
}
}
}
throw new Exception("Many concurrency calls");
}
Этот метод получает инкрементное число для указанного вида и обрабатывает проблему параллелизма, используя его, мы можем установить значение Number для каждого объекта MyEntity.Код клиента может выглядеть следующим образом:
var entity = new MyEntity();
var number = GetNumber(entity.IdKind);
entity.Number = number;
db.MyEntities.Add(entity);
db.SaveChanges();
Этот код может быть подвергнут рефакторингу, что делает установщики частными, создавая фабрику, которая гарантирует, что сущности всегда создаются с использованием метода GetNumber и использования репозиториев для управления базой данных.