У меня проблема с Entity Framework в Asp.net. Я хочу получить значение Id, когда я добавляю объект в базу данных. Как я могу это сделать?
Как я могу получить идентификатор вставленного объекта в инфраструктуре Entity?
Ответ 1
Это довольно легко. Если вы используете идентификаторы сгенерированных БД (например, IDENTITY
в MS SQL), вам просто нужно добавить сущность к ObjectSet
и SaveChanges
в соответствующий ObjectContext
. Id
будет автоматически заполняться для вас:
using (var context = new MyContext())
{
context.MyEntities.AddObject(myNewObject);
context.SaveChanges();
int id = myNewObject.Id; // Yes it here
}
Структура объекта по умолчанию следует за каждым INSERT
с SELECT SCOPE_IDENTITY()
при использовании автоматического сгенерированного Id
.
Ответ 2
Я использовал Ladislav Mrnka answer, чтобы успешно получить идентификаторы при использовании Entity Framework, но я размещаю здесь, потому что я пропустил его использование (т.е. используя его где это не требовалось) и подумал, что я опубликую свои результаты здесь, в случае, если люди хотят "решить" мою проблему.
Рассмотрим объект Order, который имеет отношения с внешним клиентом. Когда я добавил нового клиента и новый заказ одновременно, я делал что-то вроде этого:
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
Однако в моем случае это не требовалось, потому что у меня была связь внешнего ключа между клиентом. Ид. и 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, из-за использования голосового ответа сверху для чего-то, что может не потребоваться.
Ответ 3
Вам необходимо перезагрузить объект после сохранения изменений. Потому что он был изменен триггером базы данных, который не может быть отслежен EF. Так что нам нужно перезагрузить сущность снова из БД,
db.Entry(MyNewObject).GetDatabaseValues();
затем
int id = myNewObject.Id;
Посмотрите на ответ @jayantha в следующем вопросе:
Поиск @христианского ответа в следующем вопросе тоже может помочь:
Ответ 4
Пожалуйста, обратитесь к этой ссылке.
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
}
Ответ 5
Объект, который вы сохраняете, должен иметь правильный Id
после распространения изменений в базе данных.
Ответ 6
Repository.addorupdate(entity, entity.id);
Repository.savechanges();
Var id = entity.id;
Это будет работать.
Ответ 7
Вы можете получить идентификатор только после сохранения, вместо этого вы можете создать новый Guid и назначить перед сохранением.
Ответ 8
Я сталкиваюсь с ситуацией, когда мне нужно вставить данные в базу данных и одновременно потребовать первичный идентификатор, используя структуру сущности. Решение:
long id;
IGenericQueryRepository<myentityclass, Entityname> InfoBase = null;
try
{
InfoBase = new GenericQueryRepository<myentityclass, Entityname>();
InfoBase.Add(generalinfo);
InfoBase.Context.SaveChanges();
id = entityclassobj.ID;
return id;
}
Ответ 9
Есть две стратегии:
-
Использовать сгенерированный базой данных
ID
(int
илиGUID
)Минусы:
Вы должны выполнить
SaveChanges()
чтобы получитьID
только что сохраненных объектов.Плюсы:
Можно использовать
int
идентичности. -
Используйте сгенерированный клиентом
ID
- только GUID.Плюсы: минимизация операций
SaveChanges
. Возможность вставлять большой граф новых объектов за одну операцию.Минусы:
Разрешено только для
GUID
Ответ 10
Все ответы очень хорошо подходят для их собственных сценариев, но я отличался тем, что назначил 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:
Ответ 11
При первом использовании кода EF 6.x
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
и инициализировать таблицу базы данных, он поместит
(newsequentialid())
внутри свойств таблицы под заголовком "Значение по умолчанию" или "Связывание", что позволяет заполнять идентификатор при его вставке.
Проблема в том, что если вы создадите таблицу и добавите
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
часть позже, будущие update-database не добавят обратно (newsequentialid())
Чтобы исправить это, нужно стереть миграцию, удалить базу данных и перенастроить... или вы можете просто добавить (newsequentialid()) в конструктор таблиц.