У мене проблема з Entity Framework в Asp.net. Я хочу отримати значення Id щоразу, коли я додаю об'єкт у базу даних. Як я можу це зробити?
SaveChanges
відразу, щоб отримати ідентифікатор. Подальше читання тут .
У мене проблема з Entity Framework в Asp.net. Я хочу отримати значення Id щоразу, коли я додаю об'єкт у базу даних. Як я можу це зробити?
SaveChanges
відразу, щоб отримати ідентифікатор. Подальше читання тут .
Відповіді:
Це досить просто. Якщо ви використовуєте генеровані БД ідентифікатори (наприклад, 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
}
Кожна структура за замовчуванням слідує за кожним 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
Однак у моєму випадку цього не потрібно, оскільки у мене виникли зовнішні ключові відносини між замовником.Ід та замовленням. Замовник
Все, що я мав зробити, це було;
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 у нижченаведеному питанні:
Як я можу отримати Id вставленої сутності в рамках Entity при використанні defaultValue?
Подивіться на відповідь @hristian у нижченаведеному питанні:
.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
була для мене відсутнім твором.
Об'єкт, який ви зберігаєте, повинен мати правильний результат Id
після розповсюдження змін у базі даних.
Ідентифікатор можна отримати лише після збереження, натомість ви можете створити новий Посібник та призначити його перед збереженням.
Мені трапляється ситуація, коли мені потрібно вставити дані в базу даних і одночасно вимагати основний ідентифікатор, використовуючи структуру сутності. Рішення:
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
конструкторі s. АБО ви використовуєте ядро 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; }
і ініціалізувати таблицю бази даних, вона поставить a
(newsequentialid())
всередині властивостей таблиці під заголовком Значення за замовчуванням або Прив'язка, що дозволяє заповнювати ідентифікатор під час його вставки.
Проблема полягає в тому, якщо ви створите таблицю і додасте
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
частина пізніше майбутні бази оновлень не додадуть назад (newsequentialid ())
Виправити правильний спосіб - це стерти міграцію, видалити базу даних та повторно перемістити ... або просто додати (newsequentialid ()) у дизайнер таблиці.
when -column- is NULL, then NEWID()