Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 首先使用EF代码控制属性唯一性的最佳方法_C#_Entity Framework_Code First - Fatal编程技术网

C# 首先使用EF代码控制属性唯一性的最佳方法

C# 首先使用EF代码控制属性唯一性的最佳方法,c#,entity-framework,code-first,C#,Entity Framework,Code First,我有一个类用户,它的属性名必须是唯一的。 到目前为止,我已经研究了3种检查方法: 注释 [StringLength(100)] [Index(IsUnique = true)] public string Name { get; set; } 问题是,通过尝试插入具有重复名称的用户,它会抛出以下示例: 正如您所看到的,我必须导航到内部异常(我不知道是否可能,但我假设可能),最后一个内部异常的消息根本不便于用户使用 Fluent Api 我没有试过,但我相信它和注释有同样的问题 手

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

  • 注释

    [StringLength(100)]
    [Index(IsUnique = true)]
    public string Name { get; set; }
    
问题是,通过尝试插入具有重复名称的用户,它会抛出以下示例: 正如您所看到的,我必须导航到内部异常(我不知道是否可能,但我假设可能),最后一个内部异常的消息根本不便于用户使用

  • Fluent Api

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

  • 手工检查
控制器代码:

    [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
时始终必须捕获异常,但这无论如何都不是一个坏主意

对于唯一性检查,您可以使用我描述的机制,只需将
电子邮件
更改为
名称
,就可以了

您可以通过以下扩展方法从内部异常链中挖掘最后一条异常消息:

public static string GetDeepestExceptionMessage(this Exception exception)
{
    string msg = string.Empty;
    while (exception != null)
    {
        msg = exception.Message;
        exception = exception.InnerException;
    }
    return msg;
}

实际上,当并发用户最终设法插入相同的记录时,您应该同时执行这两项操作:签入代码和唯一性索引,作为最后的保护。(因为检查和实际插入之间存在延迟)

这意味着您在调用
SaveChanges
时始终必须捕获异常,但这无论如何都不是一个坏主意

对于唯一性检查,您可以使用我描述的机制,只需将
电子邮件
更改为
名称
,就可以了

您可以通过以下扩展方法从内部异常链中挖掘最后一条异常消息:

public static string GetDeepestExceptionMessage(this Exception exception)
{
    string msg = string.Empty;
    while (exception != null)
    {
        msg = exception.Message;
        exception = exception.InnerException;
    }
    return msg;
}