Get the first element with one match, or the first if there is no match?

Is it possible in LINQ to write a nice one-line file to get the item with the first match, or if there is no match, than to get the first item in the collection?

eg. you have a collection of parrots and you want a yellow parrot, but if there are no yellow parrots then anyone would do something like this:

Parrots.MatchedOrFirst(x => x.Yellow == true)

      

I'm trying to avoid a double switch to SQL Server, and the ORM we're using in this particular case is Dapper .

+3


source to share


3 answers


Edit: this was a linq to SQL solution

First, create a handy extension

public static T MatchedOrFirstOrDefault<T>(this IQueryable<T> collection, System.Linq.Expressions.Expression<Func<T, Boolean>> predicate)
{
  return (from item in collection.Where(predicate) select item)
                    .Concat((from item in collection select item).Take(1))
                    .ToList() // Convert to query result
                    .FirstOrDefault();
}

      



Using code

var matchedOrFirst = Parrots.MatchedOrFirstOrDefault(x => x.Yellow);

      

+2


source


What about:

var matchedOrFirst = Parrots.FirstOrDefault(x => x.Yellow == true) 
    ?? Parrots.FirstOrDefault();

      

Edit



For structs, this should work:

var matchedOrFirst = Parrots.Any(x => x.Yellow == true) 
    ? Parrots.First(x => x.Yellow == true)
    : Parrots.FirstOrDefault();

      

+3


source


If you want to avoid the second call to SQL, and since it requires branching logic, it is unlikely that Dapper will know how to transform the LINQ query you come up with to the corresponding SQL IIF, CASE, or any other SQL specific functions. using.

I recommend that you write a simple stored procedure for this and call it from Dapper.

However, depending on its use, if this page already has one or two queries on it and it is located close enough (latently) to the server, a second simple SELECT will not harm the overall application. Unless it is in a loop or whatever, or your example is trivial compared to the actual query regarding the cost of the first SELECT.

0


source







All Articles