我想使用数据库中最后插入的ID,但是该ID为字符串格式。有什么方法可以获取最后插入的字符串ID?
每次使用
p.UserId = db.AspNetUsers.Max(m => m.Id);
,但返回错误结果。我认为这是字符串,因此max无法使用。有人可以建议如何解决这个问题吗?
表结构:
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)
)
示例ID的格式如下:62d8d072-5261-4aaf-b552-d75453cc3421
这是代码,首先我从AspNetUsers表的视图中获取值,因此它将在表中生成ID,并且我想将该ID用于我的Patient表。
[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);
}
}
答案 0 :(得分:0)
通常,使用EF可以映射实体与FK的关系,并在保存主记录和关联记录时让EF管理FK的分配。但是,在您的情况下,这种关系是相对松散的。
所有患者记录是否都将与ASP.Net身份验证用户相关联?如果是这样,您可以查看更改Patient上的PK类型以匹配ASPNet表,然后将Patient设置为与ASPNetUser一对一的关系。
或者,如果患者可以是ASPNetUsers(但也可以分离),那么我会考虑将PatientId列作为自动递增的整数或顺序GUID(newsequentialId())添加到ASPNetUser,并将其映射为Patient可选或要求多对一。这避免了ASPNetUser上字符串PK的麻烦,并允许您使用更适合您的应用程序的FK类型。 (整数或GUID)
您可以用来获取新插入的PK的第三个选项; PK将仅在DbContext SaveChanges之后创建,因此,您需要两次调用SaveChanges以获得第一个ID:
//...
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成功但第二个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约束来管理级联删除之类的事情。
答案 1 :(得分:-1)
我了解您要获取数据库中最后插入的字段。
为什么不使用Last()函数。 :)
p.UserId = db.AspNetUsers.Select(X=>x.id).Last();
将从表格的最后一行为您提供Userid。
Max正在选择可能会或可能不会产生最后一个值的最大值。