C# 使用Single和SingleOrDefault之间的逻辑区别是什么?

C# 使用Single和SingleOrDefault之间的逻辑区别是什么?,c#,asp.net-mvc,entity-framework,asp.net-mvc-5,C#,Asp.net Mvc,Entity Framework,Asp.net Mvc 5,我不确定在哪里使用Single,在哪里使用SingleOrDefault。我理解两者的定义 单一: try { var x = someEnumerable.Single(); } catch (InvalidOperationException) { //Did not contain exactly one record } 它将始终返回一行 如果没有找到行,我将得到一个异常 如果找到多行,我将得到一个异常 SingleOrDefault: var y = someEnum

我不确定在哪里使用
Single
,在哪里使用
SingleOrDefault
。我理解两者的定义

单一:

try
{
    var x = someEnumerable.Single();
}
catch (InvalidOperationException)
{
    //Did not contain exactly one record
}
  • 它将始终返回一行

  • 如果没有找到行,我将得到一个异常

  • 如果找到多行,我将得到一个异常

  • SingleOrDefault:

    var y = someEnumerable.SingleOrDefault();
    if (y == null)
    {
        //Did not contain exactly one record
    }
    
  • 它将始终返回一行,如果未找到,则返回默认值
    (此默认值的含义是什么”)。

  • 如果有多行,则异常

  • 问题1:“它将返回默认值”的含义是什么

    问题2:何时使用Single以及何时使用SingleOrDefault

    我有一个删除功能,其中我有以下代码:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Delete(int resumeId)
    {
        var r = _context
            .Resumes
            .Where(c => c.ResumeId == resumeId).SingleOrDefault();
        _context.Resumes.Remove(r);
        _context.SaveChanges();
    
        return RedirectToAction("ResumeCenter");
    }
    

    我只是盲目地把
    SingleOrDefault
    放在任何地方(我不希望有一个值),请告诉我一个真实的场景,我应该在什么时候使用“Single”和在什么地方使用“SingleOrDefault”。

    当你知道数据库中的某些东西必须有一个值时,请使用
    Single()
    因为如果数据库中不存在“非常期望的值”,您可能希望获得异常。特定员工代码的EmployeeName等数据

    当您知道员工是临时员工且其部门可能不会显示在主数据库中时,请使用SingleOrDefault()。但是,如果department的值存在,则该值应仅为一个值。他不会同时为多个部门工作

    Single()-数据存储中至少需要一个值,并且您需要它。您需要知道是否没有值或有多个值。在这种情况下,您会得到一个异常并进行检查


    SingleOrDefault()-如果一条记录不存在,则使用默认值给出它。不管该记录是否有任何可用记录。但它不应该是多条记录。

    当您知道数据库中的某些内容必须有一个值时,请使用
    Single()
    因为如果数据库中不存在“非常期望的值”,您可能希望获得异常。特定员工代码的EmployeeName等数据

    当您知道员工是临时员工且其部门可能不会显示在主数据库中时,请使用SingleOrDefault()。但是,如果department的值存在,则该值应仅为一个值。他不会同时为多个部门工作

    Single()-数据存储中至少需要一个值,并且您需要它。您需要知道是否没有值或有多个值。在这种情况下,您会得到一个异常并进行检查

    SingleOrDefault()-如果一条记录不存在,则使用默认值给出它。不管该记录是否有任何可用项。但它不应该是多条记录。

    这几乎是(但不是完全)风格问题。您更喜欢哪一条

    单一:

    try
    {
        var x = someEnumerable.Single();
    }
    catch (InvalidOperationException)
    {
        //Did not contain exactly one record
    }
    
    SingleOrDefault:

    var y = someEnumerable.SingleOrDefault();
    if (y == null)
    {
        //Did not contain exactly one record
    }
    
    基于异常的方法需要更多的编码,但它很好,因为可以允许异常冒泡。也就是说,我通常使用
    XXXOrDefault
    变量来避免堆栈展开,这可能会降低性能。通常,在预期行为时,应该避免抛出异常

    另外,任何类型的“默认值”都可以通过使用来获得。对于整数,它是零;对于日期,它是MinValue;对于引用类型,它是null,等等

    p.p.S.在您的示例中,我将使用
    Single
    ,并允许在缺少行或有多行时引发异常。否则,您可能会将
    null
    传递给后续的
    Remove
    方法。虽然这也会失败,但它会比应该失败的行晚一行,从而导致虚假的堆栈跟踪和使故障排除变得更加棘手

    OTOH,只要稍作改动,您就可以使其中一个工作:

    public ActionResult Delete(int resumeId)
    {
        var r = _context
            .Resumes
            .Where(c => c.ResumeId == resumeId).SingleOrDefault();
        if (r == null)
        {
            return RedirectToAction("ErrorPage");
        }
        else
        {
            _context.Resumes.Remove(r);
            _context.SaveChanges();
            return RedirectToAction("ResumeCenter");
        }
    }
    

    这几乎(但不完全)是一个风格问题。你更喜欢哪一种

    单一:

    try
    {
        var x = someEnumerable.Single();
    }
    catch (InvalidOperationException)
    {
        //Did not contain exactly one record
    }
    
    SingleOrDefault:

    var y = someEnumerable.SingleOrDefault();
    if (y == null)
    {
        //Did not contain exactly one record
    }
    
    基于异常的方法需要更多的编码,但它很好,因为可以允许异常冒泡。也就是说,我通常使用
    XXXOrDefault
    变量来避免堆栈展开,这可能会降低性能。通常,在预期行为时,应该避免抛出异常

    另外,任何类型的“默认值”都可以通过使用来获得。对于整数,它是零;对于日期,它是MinValue;对于引用类型,它是null,等等

    p.p.S.在您的示例中,我将使用
    Single
    ,并允许在缺少行或有多行时引发异常。否则,您可能会将
    null
    传递给后续的
    Remove
    方法。虽然这也会失败,但它会比应该失败的行晚一行,从而导致虚假的堆栈跟踪和使故障排除变得更加棘手

    OTOH,只要稍作改动,您就可以使其中一个工作:

    public ActionResult Delete(int resumeId)
    {
        var r = _context
            .Resumes
            .Where(c => c.ResumeId == resumeId).SingleOrDefault();
        if (r == null)
        {
            return RedirectToAction("ErrorPage");
        }
        else
        {
            _context.Resumes.Remove(r);
            _context.SaveChanges();
            return RedirectToAction("ResumeCenter");
        }
    }
    


    正如你说的函数名所暗示的那样

    list.single();
    
    那就意味着

    “我想要名单上的单曲”,因此你得到了单曲 记录(第一条)”

    当你说

    list.SingleOrDefault();
    
    那就意味着

    “我想要一张唱片,如果唱片不存在,我会 希望具有对象的默认值“

    完全是你的办法,你也可以去

    FirstOrDefault(); 
    

    就像你说的函数名所建议的单个或默认值一样

    list.single();
    
    那就意味着

    “我想要名单上的单曲”,因此你得到了单曲 记录(第一条)”

    当你说

    list.SingleOrDefault();
    
    那就意味着

    “我想要一张唱片,如果唱片不存在,我会 希望具有对象的默认值“

    完全是你的办法,你也可以去

    FirstOrDefault(); 
    
    就像你说的单一或默认
    Single()
    如果找不到行,将引发异常。
    Si