使用 EF Code First 控制属性唯一性的最佳方法
Best way to control unicity of an attribute using EF Code First
我有一个 class 用户,它的属性名称必须是唯一的。
到目前为止,我已经研究了 3 种检查方法:
注释
[StringLength(100)]
[Index(IsUnique = true)]
public string Name { get; set; }
问题是,通过尝试插入一个具有重复名称的用户,它会抛出这个 ex:
如您所见,我将不得不导航到内部异常(我不知道是否可能,但我认为是)并且最后一个内部异常的消息根本不是用户友好的。
- 流利Api
我没试过,但我相信它和 Annotations 有同样的问题。
- 手工检查
控制器代码:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Name,Password,Profile")] User user)
{
if (ModelState.IsValid)
{
lock (locker)
{
validateNameUnicity();
db.Users.Add(user);
db.SaveChanges();
}
return RedirectToAction("Index");
}
return View(user);
}
问题:检查取决于我的代码,它可能不如日期库检查准确。此外,我将需要编写比其他两个选项更多的逻辑。最后但同样重要的是,如果我以某种方式直接访问数据库,则根本不会进行检查。
我需要知道执行此操作的最佳做法是什么,因为我正在努力自学,并且我希望尽可能做到最好。
您实际上应该同时执行这两项操作,签入代码 和 唯一性索引作为并发用户设法插入相同记录的最终保护。 (由于检查和实际插入之间的延迟)。
这意味着您在调用 SaveChanges
时总是必须捕获异常,但无论如何这不是一个坏主意。
对于唯一性检查,您可以使用我描述的机制 here,只需将 email
更改为 Name
即可。
您可以通过此扩展方法从内部异常链中挖掘出最后一条异常消息:
public static string GetDeepestExceptionMessage(this Exception exception)
{
string msg = string.Empty;
while (exception != null)
{
msg = exception.Message;
exception = exception.InnerException;
}
return msg;
}
我有一个 class 用户,它的属性名称必须是唯一的。 到目前为止,我已经研究了 3 种检查方法:
注释
[StringLength(100)] [Index(IsUnique = true)] public string Name { get; set; }
问题是,通过尝试插入一个具有重复名称的用户,它会抛出这个 ex:
- 流利Api
我没试过,但我相信它和 Annotations 有同样的问题。
- 手工检查
控制器代码:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Name,Password,Profile")] User user)
{
if (ModelState.IsValid)
{
lock (locker)
{
validateNameUnicity();
db.Users.Add(user);
db.SaveChanges();
}
return RedirectToAction("Index");
}
return View(user);
}
问题:检查取决于我的代码,它可能不如日期库检查准确。此外,我将需要编写比其他两个选项更多的逻辑。最后但同样重要的是,如果我以某种方式直接访问数据库,则根本不会进行检查。
我需要知道执行此操作的最佳做法是什么,因为我正在努力自学,并且我希望尽可能做到最好。
您实际上应该同时执行这两项操作,签入代码 和 唯一性索引作为并发用户设法插入相同记录的最终保护。 (由于检查和实际插入之间的延迟)。
这意味着您在调用 SaveChanges
时总是必须捕获异常,但无论如何这不是一个坏主意。
对于唯一性检查,您可以使用我描述的机制 here,只需将 email
更改为 Name
即可。
您可以通过此扩展方法从内部异常链中挖掘出最后一条异常消息:
public static string GetDeepestExceptionMessage(this Exception exception)
{
string msg = string.Empty;
while (exception != null)
{
msg = exception.Message;
exception = exception.InnerException;
}
return msg;
}