У меня проблема с Entity Framework в Asp.net. Я хочу получить значение Id всякий раз, когда я добавляю объект в базу данных. Как я могу это сделать?
SaveChanges
прямо сейчас, чтобы получить удостоверение личности. Дальнейшее чтение здесь .
У меня проблема с Entity Framework в Asp.net. Я хочу получить значение Id всякий раз, когда я добавляю объект в базу данных. Как я могу это сделать?
SaveChanges
прямо сейчас, чтобы получить удостоверение личности. Дальнейшее чтение здесь .
Ответы:
Это довольно легко. Если вы используете DB генерируется Идентификаторы (например , IDENTITY
в MS SQL) вам просто нужно добавить объект к ObjectSet
и SaveChanges
на связанные ObjectContext
. Id
будет автоматически заполнено для вас:
using (var context = new MyContext())
{
context.MyEntities.Add(myNewObject);
context.SaveChanges();
int id = myNewObject.Id; // Yes it's here
}
Рамки Entity по умолчанию следует каждый INSERT
с , SELECT SCOPE_IDENTITY()
когда автоматически генерируемые Id
используются s.
Я использовал ответ Ладислава Мрнки для успешного получения идентификаторов при использовании Entity Framework, однако я публикую здесь, потому что я его не использовал (т. Е. Использовал там, где это не требовалось) и думал, что я опубликую свои выводы здесь, Если люди хотят «решить» проблему, которая у меня была.
Рассмотрим объект Заказа, который имеет отношение внешнего ключа с Клиентом. Когда я добавил нового клиента и новый заказ одновременно, я делал что-то вроде этого;
var customer = new Customer(); //no Id yet;
var order = new Order(); //requires Customer.Id to link it to customer;
context.Customers.Add(customer);
context.SaveChanges();//this generates the Id for customer
order.CustomerId = customer.Id;//finally I can set the Id
Однако в моем случае это не требовалось, потому что у меня были отношения внешнего ключа между customer.Id и order.CustomerId
Все, что мне нужно было сделать, это;
var customer = new Customer(); //no Id yet;
var order = new Order{Customer = customer};
context.SaveChanges();//adds customer.Id to customer and the correct CustomerId to order
Теперь, когда я сохраняю изменения, идентификатор, который генерируется для клиента, также добавляется в заказ. Мне не нужны дополнительные шаги
Я знаю, что это не отвечает на первоначальный вопрос, но я подумал, что это может помочь разработчикам, которые плохо знакомы с EF, чрезмерно использовать ответ с верхним голосом для чего-то, что может не потребоваться.
Это также означает, что обновления завершаются за одну транзакцию, что может привести к потере данных о потерях (либо все обновления завершены, либо нет).
Вам необходимо перезагрузить объект после сохранения изменений. Потому что он был изменен триггером базы данных, который не может быть отслежен EF. Так что нам нужно перезагрузить сущность снова из БД,
db.Entry(MyNewObject).GetDatabaseValues();
затем
int id = myNewObject.Id;
Посмотрите на ответ @jayantha в следующем вопросе:
Поиск @христианского ответа в следующем вопросе тоже может помочь:
.GetDatabaseValues();
если вы просто сохранили свою модель в БД. Идентификатор должен автоматически заполнить модель.
GetDatabaseValues()
если он не знает идентификатор объекта, который нужно искать в базе данных?
Пожалуйста, обратитесь по этой ссылке.
http://www.ladislavmrnka.com/2011/03/the-bug-in-storegeneratedpattern-fixed-in-vs-2010-sp1/
Вы должны установить свойство StoreGeneratedPattern в идентичность и затем попробовать свой собственный код.
Или вы также можете использовать это.
using (var context = new MyContext())
{
context.MyEntities.AddObject(myNewObject);
context.SaveChanges();
int id = myNewObject.Id; // Your Identity column ID
}
StoreGeneratedPattern
был недостающий кусок для меня.
Вы можете получить идентификатор только после сохранения, вместо этого вы можете создать новый Guid и назначить перед сохранением.
Я сталкиваюсь с ситуацией, когда мне нужно вставить данные в базу данных и одновременно потребовать первичный идентификатор, используя структуру сущностей. Решение :
long id;
IGenericQueryRepository<myentityclass, Entityname> InfoBase = null;
try
{
InfoBase = new GenericQueryRepository<myentityclass, Entityname>();
InfoBase.Add(generalinfo);
InfoBase.Context.SaveChanges();
id = entityclassobj.ID;
return id;
}
Все ответы очень хорошо подходят для их собственных сценариев, но я отличался тем, что назначил int PK непосредственно из объекта (TEntity), который Add () возвратил в переменную int, подобную этой;
using (Entities entities = new Entities())
{
int employeeId = entities.Employee.Add(new Employee
{
EmployeeName = employeeComplexModel.EmployeeName,
EmployeeCreatedDate = DateTime.Now,
EmployeeUpdatedDate = DateTime.Now,
EmployeeStatus = true
}).EmployeeId;
//...use id for other work
}
поэтому вместо создания нового объекта вы просто берете то, что хотите :)
РЕДАКТИРОВАТЬ Для г-на @GertArnold:
Add
(если это так DbSet.Add
) не магическим образом присваивает значение EmployeeId
.
SaveChanges
. Невозможно. Если у вас нет другого процесса, который присваивает EmployeeId
, например, в Employee
конструкторе. ИЛИ вы используете ядро EF ForSqlServerUseSequenceHiLo
. Во всяком случае, вы не даете всю картину.
Repository.addorupdate(entity, entity.id);
Repository.savechanges();
Var id = entity.id;
Это будет работать
Repository
такое. И «это сработает» - какое-то объяснение!
Есть две стратегии:
Использовать базу данных ID
( int
или GUID
)
Минусы:
Вы должны выполнить, SaveChanges()
чтобы получить ID
только что сохраненные объекты.
Плюсы:
Можно использовать int
личность.
Использовать сгенерированный клиент ID
- только GUID.
Плюсы: минимизация SaveChanges
операций. Возможность вставлять большой граф новых объектов за одну операцию.
Минусы:
Разрешено только для GUID
При первом использовании кода EF 6.x
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
и инициализировать таблицу базы данных, он поместит
(newsequentialid())
в свойствах таблицы под заголовком «Значение по умолчанию» или «Связывание», позволяя заполнять идентификатор при его вставке.
Проблема в том, что если вы создадите таблицу и добавите
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
часть позже, будущие update-database не добавят обратно (newsequentialid ())
Чтобы исправить это, нужно стереть миграцию, удалить базу данных и перенастроить ... или вы можете просто добавить (newsequentialid ()) в конструктор таблиц.
when -column- is NULL, then NEWID()