LINQ: When to use SingleOrDefault vs. FirstOrDefault() with filtering criteria

前端 未结 15 1004
我在风中等你
我在风中等你 2020-11-22 12:48

Consider the IEnumerable extension methods SingleOrDefault() and FirstOrDefault()

MSDN documents that SingleOrDefault:

相关标签:
15条回答
  • 2020-11-22 13:17

    I queried Google for the usage of the different methods on GitHub. This is done by running a Google search query for each method and limiting the query to the github.com domain and the .cs file extension by using the query "site:github.com file:cs ..."

    It seems that the First* methods are more commonly used than the Single* methods.

    | Method               | Results |
    |----------------------|---------|
    | FirstAsync           |     315 |
    | SingleAsync          |     166 |
    | FirstOrDefaultAsync  |     357 |
    | SingleOrDefaultAsync |     237 |
    | FirstOrDefault       |   17400 |
    | SingleOrDefault      |    2950 |
    
    0 讨论(0)
  • 2020-11-22 13:18

    If your result set returns 0 records:

    • SingleOrDefault returns the default value for the type (e.g. default for int is 0)
    • FirstOrDefault returns the default value for the type

    If you result set returns 1 record:

    • SingleOrDefault returns that record
    • FirstOrDefault returns that record

    If your result set returns many records:

    • SingleOrDefault throws an exception
    • FirstOrDefault returns the first record

    Conclusion:

    If you want an exception to be thrown if the result set contains many records, use SingleOrDefault.

    If you always want 1 record no matter what the result set contains, use FirstOrDefault

    0 讨论(0)
  • 2020-11-22 13:18

    Both are the element operators and they are used to select a single element from a sequence. But there is a minor difference between them. SingleOrDefault() operator would throw an exception if more than one elements are satisfied the condition where as FirstOrDefault() will not throw any exception for the same. Here is the example.

    List<int> items = new List<int>() {9,10,9};
    //Returns the first element of a sequence after satisfied the condition more than one elements
    int result1 = items.Where(item => item == 9).FirstOrDefault();
    //Throw the exception after satisfied the condition more than one elements
    int result3 = items.Where(item => item == 9).SingleOrDefault();
    
    0 讨论(0)
  • 2020-11-22 13:20

    Nobody has mentioned that FirstOrDefault translated in SQL does TOP 1 record, and SingleOrDefault does TOP 2, because it needs to know is there more than 1 record.

    0 讨论(0)
  • 2020-11-22 13:20

    SingleOrDefault: You're saying that "At most" there is one item matching the query or default FirstOrDefault: You're saying that there is "At least" one item matching the query or default

    Say that out loud next time you need to choose and you shall likely choose wisely. :)

    0 讨论(0)
  • 2020-11-22 13:24

    One thing that is missed in the responses....

    If there are multiple results, FirstOrDefault without an order by can bring back different results based on which ever index strategy happened to be used by the server.

    Personally I cannot stand seeing FirstOrDefault in code because to me it says the developer didn't care about the results. With an order by though it can be useful as a way of enforcing the latest/earliest. I've had to correct a lot of issues caused by careless developers using FirstOrDefault.

    0 讨论(0)
提交回复
热议问题