Entity Framework 4.1 Code First - поле автоматического увеличения при вставке для не первичного ключа - PullRequest
3 голосов
/ 05 июля 2011

Моя модель содержит Заказ (родительский объект) и Отгрузки (дочерний объект). Таблица базы данных для них уже имеет суррогатный ключ в качестве первичного ключа с автоинкрементом.

У меня есть бизнес-правило, которое заключается в том, что для каждой отгрузки в заказе нам нужно иметь автоматически сгенерированное поле "счетчик" - например, Отгрузка 1, Отгрузка 2, Отгрузка 3 и т. Д. Модель отгрузки имеет свойства: «ShipmentId», «OrderId», «ShipmentNumber». Моя попытка реализации заключается в том, чтобы ShipmentNumber содержал int и in code (в отличие от базы данных), запрашивал коллекцию Shipment и выполнял max () + 1.

Вот фрагмент кода того, что я делаю.

        Shipment newShipmentObj = // blah;

        int? currentMaxId = myOrderObj.Shipments
                            .Select(x => (int?) x.ShipmentNumber)
                            .Max();
            if (currentMaxId.HasValue)
                newShipmentObj.ShipmentNumber = currentMaxId.Value + 1;
            else
                newShipmentObj.ShipmentNumber = 1; // 1st one

        myOrderObj.Shipments.Add(newShipmentObj);

        // etc.. rest of EF4 code

Есть ли лучший способ?

Мне не очень нравится это, потому что у меня есть следующие проблемы из-за потенциальных проблем транзакций / параллелизма.

Объект My Order также имеет автоинкрементный "счетчик" - например, Модель Order 1, Order 2, Order 3, ... My Order имеет свойства: "OrderId", "CustomerId", "OrderNumber".

Мой дизайн таков, что у меня есть OrderRepository, но не ShipmentRepository. Репозиторий Shipment может запрашивать коллекцию Order.Shipment ... но с помощью Orders мне нужно запросить непосредственно из dbcontext, например,

        int? currentMaxId = (_myDbContext)).Orders
                        .Where(x => x.CustomerId == 123456)
                        .Select(x => (int?)x.OrderNumber)
                        .Max();

Однако вышеприведенная часть не работает, если я пытаюсь добавить несколько объектов в DbContext без фиксации / сохранения изменений в базе данных. (то есть .Where () возвращает ноль ... и работает, только если я использую DbContext ".Local", а это не то, что я хочу.)

Помощь! Не уверен, что будет лучшим решением. Спасибо!

1 Ответ

0 голосов
/ 25 ноября 2011

у вас, похоже, уже есть shipmentid, который является инкрементным. Вы можете использовать его для своего номера отгрузки и, возможно, в сочетании с текущей датой, как описано здесь: Как внедрить в NHibernate простые, удобные для пользователя идентификаторы? то, что вы пытаетесь сделать с Максом (), является злом. Держитесь подальше от него, так как это может вызвать проблемы с получением одинаковых номеров для нескольких отправлений при высокой загрузке

...