locked
SingleOrDefault Question RRS feed

  • Question

  • User941905567 posted

    Can someone explain to me the difference between the first statement, (Which blows up if "CA" is not in the list), and the second statement (Which does not blow up is CA is not in the list). Any explaination would be most appreciated.

    --Jason

    Qp.Discounts.ToList.SingleOrDefault(Function(x) x.GovState = "CA").BtisServiceFee

    vs

    Qp.Discounts.ToList.Where(Function(x) x.GovState = "CA").Select(Function(x) x.BtisServiceFee).SingleOrDefault

    Tuesday, July 17, 2018 5:00 PM

Answers

  • User753101303 posted

    Hi,

    In the first case you retrieve the only object from a list or the default value (which is null for an object) and then try to access a property (which will fail if the object is null).

    In the second case you "select" a single property for each item of a list (which works even if the list is empty as then there is just nothing to process) and then only you return the single property value you found or the default value for this property type (maybe 0 rather than null ?)

    Also ToList is called earlier which should force all rows being retrieved from the db and the filtering to happen on the client side. Here it is not needed at all as SingleOrDefault will trigger the query and it would allow the WHERE clause to be processed on the db side.

    So in short my preference could be :

    Qp.Discounts.Select(Function(x) x.BtisServiceFee).SingleOrDefault(Function(x) x.GovState = "CA") ' SELECT BtisServiceFee FROM t WHERE GovState='CA'

    I would even perhaps use Single (so that you don't get 0 because someone forgot to add "CA" to a list of states).

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, July 17, 2018 6:09 PM

All replies

  • User475983607 posted

    If "CA" does not exist then the logic looks like below and null does not have a BtisServiceFee property.

    null.BtisServiceFee

    This syntax is allowed to return null.

    Qp.Discounts.ToList.Where(Function(x) x.GovState = "CA").Select(Function(x) x.BtisServiceFee).SingleOrDefault

    Also the use of ToList might indicate a code smell.

    Tuesday, July 17, 2018 5:31 PM
  • User753101303 posted

    Hi,

    In the first case you retrieve the only object from a list or the default value (which is null for an object) and then try to access a property (which will fail if the object is null).

    In the second case you "select" a single property for each item of a list (which works even if the list is empty as then there is just nothing to process) and then only you return the single property value you found or the default value for this property type (maybe 0 rather than null ?)

    Also ToList is called earlier which should force all rows being retrieved from the db and the filtering to happen on the client side. Here it is not needed at all as SingleOrDefault will trigger the query and it would allow the WHERE clause to be processed on the db side.

    So in short my preference could be :

    Qp.Discounts.Select(Function(x) x.BtisServiceFee).SingleOrDefault(Function(x) x.GovState = "CA") ' SELECT BtisServiceFee FROM t WHERE GovState='CA'

    I would even perhaps use Single (so that you don't get 0 because someone forgot to add "CA" to a list of states).

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, July 17, 2018 6:09 PM