ИМО Идентификатор необходим, даже если он сгенерирован. Предположим, что вы используете ассоциацию внешнего ключа (другое поведение, чем независимая ассоциация). Это означает, что связанные дочерние объекты используют первичный ключ родительского объекта для построения отношения. Теперь предположим, что вы добавляете несколько родительских объектов со связанными объектами в одну единицу работы. Вы должны указать уникальный (временный) идентификатор для каждого родительского объекта, иначе вы никогда не настроите граф объекта. Поэтому генератор кода делает это по умолчанию.
Edit:
Я удивлен, что я был downvoted для ответа на основе правильных фактов.Поэтому позвольте мне уточнить мой ответ:
В EF 4.0 есть два типа отношений. Независимая ассоциация и Ассоциация внешних ключей. Различие заключается в том, что более поздняя добавляет свойства внешнего ключа к объектам. Это позволяет работать с отношениями так же, как и в базе данных, - просто установив ключи. Вы можете прочитать об этих различиях в MSDN.
Теперь давайте предположим простой пример. У меня простая модель EDMX с MyContext. Модель состоит из двух объектов Order and OrderLine. Когда я добавлял таблицы Заказы и OrderLines к модели, я загубил Включить столбцы внешних ключей в модели, поэтому я использую ассоциации внешних ключей вместо независимых ассоциаций.
Заказ имеет идентификатор магазина в виде ключа и имя CustomerName как свойство. Строка заказа имеет идентификатор хранилища в качестве ключа, ProductTitle как свойство и OrderId как внешний ключ. Я хочу добавить два порядка в одной единице работы:
using (var context = new MyContext())
{
var ox = Order.CreateOrder(0, "CustomerX");
var oy = Order.CreateOrder(0, "CustomerY");
// Building relationship in the same way as in database
var olx = OrderLine.CreateOrderLine(0, ox.Id, "ProductX");
var oly = OrderLine.CreateOrderLine(0, oy.Id, "ProductY");
context.Orders.AddObject(ox);
context.Orders.AddObject(oy);
context.OrderLines.AddObject(olx);
context.OrderLines.AddObject(oly);
context.SaveChanges(); // UpdateException: Unable determine principal end of Model.FK_OrderLine_Order relationship. Multiple added entities have the same primary key.
}
Ошибку я сделал в моем коде установка Id как новые заказы на 0. Даже если это временный идентификатор он все еще должен быть уникальными, если вы хотите использовать его для внешних ключей. Вероятно, вы можете спросить в тот момент, почему контекст не обрабатывает Id сам по себе? Просто потому, что он не может. Контекст знает, что идентификатор является временным и будет восстановлен в магазине, но контекст не знает подробностей о конфигурации магазина. Когда вы устанавливаете Identity в базе данных, вы также устанавливаете семя и приращение. Эти два значения не известны контексту, поэтому контекст не может получить действительный уникальный временный идентификатор, который еще не используется хранилищем. Предположим, что контекст неправильно создает некоторый временный идентификатор, и после этого вы загружаете объект, который уже использует эту проблему Id =.
Если я просто обновляю свой код, чтобы использовать уникальный временный идентификатор (я знаю, как настроен магазин), он будет работать. Это ИМО - одна из причин, по которой мне нужно предоставить временные методы Id для создания.
Спасибо вам Марк! Это в следующий раз, когда вы спасете меня много времени. – user278618
Хороший шаблон, но я думаю, вы были бы более безопасным, используя значение по умолчанию 0 для id .. -1 не сработало бы проверку значений по умолчанию, и можно предположить, что вы не будете создавать таблицу с идентификатором начиная с нуля. –
@daveL: отрицательные числа работают просто отлично для меня .... –