c# - 使用 EF Code First 控制属性唯一性的最佳方法

标签 c# entity-framework code-first

我有一个 User 类,它的属性 Name 必须是唯一的。 到目前为止,我已经研究了 3 种检查方法:

  • 注释

    [StringLength(100)]
    [Index(IsUnique = true)]
    public string Name { get; set; }
    

问题是,通过尝试插入一个具有重复名称的用户,它会抛出这个 ex: DbUpdateException 如您所见,我将不得不导航到内部异常(我不知道这是否可能,但我认为是可能的)并且最后一个内部异常的消息根本不是用户友好的。

  • 流畅的 API

https://stackoverflow.com/a/23155759/5750078

我还没有尝试过,但我相信它和注释有同样的问题。

  • 手工检查

Controller 代码:

    [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;
}

关于c# - 使用 EF Code First 控制属性唯一性的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41536964/

相关文章:

c# - 如何使用简单注入(inject)器模拟模块/安装程序/注册表

c# - Entity Framework 无效对象名称错误

c# Fluent SQL Helper - 语法改进

c# - LINQ to Entities 和多态性

c# - 当首先使用带有数据注释的 MVC 代码时,如何在显示名称中包含 html 标记?

entity-framework - 获取SQL以进行自动迁移的策略

c# - 没有 StackTrace 或日志的 Monotouch 应用程序崩溃(从未调用析构函数)

.net - 如何在没有互联网连接的情况下安装 NuGet 包?

entity-framework - 将存储过程映射到返回临时表数据的实体

c# - 在 Code First MVC 应用程序中查询 AspNet Identity 表