Как получить последний вставленный идентификатор (строка) из таблицы - PullRequest
0 голосов
/ 18 ноября 2018

Я хочу использовать последний вставленный идентификатор из базы данных, но этот идентификатор находится в строковом формате. Есть ли способ получить последний вставленный идентификатор строки?

Каждый раз, когда я использую

p.UserId = db.AspNetUsers.Max(m => m.Id);

но он возвращает неверные результаты. Я думаю, что это строка, поэтому Макс не будет работать. Кто-нибудь может подсказать, пожалуйста, как решить эту проблему?

Структура таблицы:

  • Пациент: ID (PK), UID (fk UserLogin), Имя

AspNetUsers таблица:

CREATE TABLE [dbo].[AspNetUsers] 
(
    [Id]    NVARCHAR(128) NOT NULL,
    [Email] NVARCHAR (256) NULL,
)

Пациент Таблица:

CREATE TABLE Patient
(
     PatientId INT IDENTITY(1,1) PRIMARY KEY,
     PId AS 'P' + RIGHT('00000' + CAST(PatientId AS NVARCHAR(10)), 10) PERSISTED,
     UserId NVARCHAR(128) FOREIGN KEY REFERENCES AspNetUsers(Id)
)

Пример идентификатора имеет следующий формат: 62d8d072-5261-4aaf-b552-d75453cc3421

Это код, сначала я получаю значение из представления в таблице AspNetUsers, поэтому он сгенерирует идентификатор в таблице, и я хочу использовать этот идентификатор для моей таблицы пациентов.

[HttpPost]
[ValidateAntiForgeryToken]
[AllowAnonymous]
public async Task<ActionResult> SignUp(Patientview pv)
{
        ClinicDbContext db = new ClinicDbContext();

        if (ModelState.IsValid)
        {
            try
            {
                var user = new ApplicationUser { UserName = pv.Email, Email = pv.Email };
                var result = await UserManager.CreateAsync(user, pv.Password);

                if (result.Succeeded)
                {
                    await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);

                }
                else
                {
                    return View(pv);
                }

                Patient p = new Patient();
                p.FirstName = pv.FirstName;
                p.LastName = pv.LastName;
                p.DateOfBirth = pv.DateOfBirth;
                p.Email = pv.Email;
                p.PhoneNumber = pv.PhoneNumber.ToString();
                p.StreetAddress = pv.StreetAddress.ToString();
                p.City = pv.City;
                p.State = pv.State;
                p.ZipCode = pv.ZipCode;
                p.UserId = db.AspNetUsers.Max(m => m.Id);

                _context.Patients.Add(p);
                _context.SaveChanges();

                return RedirectToAction("Index", "Admin");
            }
            catch (DbEntityValidationException e)
            {
                foreach (var eve in e.EntityValidationErrors)
                {
                    System.Diagnostics.Debug.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                        eve.Entry.Entity.GetType().Name, eve.Entry.State);
                    foreach (var ve in eve.ValidationErrors)
                    {
                        System.Diagnostics.Debug.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                            ve.PropertyName, ve.ErrorMessage);
                    }
                }
                throw;
            }
        }
        else
        {
            return View(pv);
        }
}

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Обычно с EF вы отображаете отношения между сущностями с FK и позволяете EF управлять назначением FK при сохранении основной записи и связанных записей. Однако в вашем случае отношения относительно слабо связаны.

Будут ли все записи пациентов связаны с аутентифицированными пользователями ASP.Net? Если это так, вы можете посмотреть на изменение типа PK в Patient в соответствии с таблицей ASPNet, а затем настроить Patient как отношение 1-к-1 к ASPNetUser.

В качестве альтернативы, если пациенты могут быть ASPNetUsers (но также могут быть разобщены), я бы посмотрел на добавление столбца PatientId в качестве автоинкрементного целого или последовательного GUID (newsequentialId ()) в ASPNetUser и сопоставление этого с PatientId в пациенте как необязательно или требуется много-к-1. Это позволяет избежать уродливости строки PK в ASPNetUser и позволяет вам использовать тип FK, который больше подходит для вашего приложения. (Int или GUID)

Третий вариант, который вы можете использовать, чтобы получить этот недавно вставленный PK; PK будет создан только после DbContext SaveChanges, поэтому вам придется дважды вызывать SaveChanges, чтобы получить первый идентификатор:

//...
var user = new ApplicationUser { UserName = pv.Email, Email = pv.Email };
var result = await UserManager.CreateAsync(user, pv.Password);

if (result.Succeeded)
  await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
else
  return View(pv);

_context.SaveChanges();
Patient p = new Patient();
p.PatientId = Guid.Parse(user.UserId); // User ID will be populated after the above SaveChanges call.                
p.FirstName = pv.FirstName;
//...
_context.SaveChanges(); //Save the Patient.

Как правило, хотя это и не идеально, так как вы можете получить ситуацию, когда первый SaveChanges завершается успешно, а второй - нет. Эти записи, вероятно, должны проходить вместе, так что это может быть достигнуто с помощью области транзакций или с помощью модуля или работы, такой как DbContextScope.

Использование TransactionScope:

using (var tx = new TransactionScope())
{ 
    var user = new ApplicationUser { UserName = pv.Email, Email = pv.Email };
    var result = await UserManager.CreateAsync(user, pv.Password);

    if (result.Succeeded)
      await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
    else
      return View(pv);

    _context.SaveChanges();
    Patient p = new Patient();
    p.PatientId = Guid.Parse(user.UserId); // User ID will be populated after the above SaveChanges call.                
    p.FirstName = pv.FirstName;
    //...
    _context.SaveChanges(); //Save the Patient.

  tx.Complete()
}

В целом, однако, отображение отношений между объектами было бы лучшим вариантом, потому что тогда ограничения FK могут быть установлены для управления такими вещами, как каскадное удаление.

0 голосов
/ 18 ноября 2018

Я понимаю, что вы хотите получить последнее вставленное поле в базе данных.

Почему бы вам не использовать функцию Last (). :)

p.UserId = db.AspNetUsers.Select(X=>x.id).Last(); 

Даст вам идентификатор пользователя из последней строки таблицы.

Макс выбирает максимальное значение, которое может или не может дать вам последнее значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...