IQueryable extension methods SingleOrNull FirstOrNull OrderBy

Tomasz Modelski

Surgery-tools

In my dev work I constantly discover that readability of code – clarity of what is going on – is very important in writing quality manageable code.

Even simple extension methods that help code to be more understandable on the first sight are useful to me.

It this post I’ll share with you two (three) simple ‘replacements’ / enhancements :

.
.

Why not just SingleOrDefault / FirstOrDefault ?

Because I’m always unsure what will be the ‘default’ value, null or some ‘default’.
I want to be absolutely sure it’s null for reference types.
In addition when Single is violated (multiple elements), I throw specific ‘typed’ exception MultipleOnSingleEx instead of InvalidOperationException for easier error handling & logging.

// ### SingleOrNull
public static T SingleOrNull(this IQueryable iQ, System.Linq.Expressions.Expression> predicate) where T : class
{
	try
	{
		var res = iQ.SingleOrDefault(predicate);
		return res == default(T) ? null : res;
	}
	catch (InvalidOperationException invOpEx)
	{
		if (invOpEx.Message == "Sequence contains more than one element")
			throw new MultipleOnSingleEx(invOpEx.Message, invOpEx);
		throw;
	}
}
public static T SingleOrNull(this IQueryable iQ) where T : class
{
	try
	{
		var res = iQ.SingleOrDefault();
		return res == default(T) ? null : res;	
	}
	catch (InvalidOperationException invOpEx)
	{
		if (invOpEx.Message == "Sequence contains more than one element")
			throw new MultipleOnSingleEx(invOpEx.Message, invOpEx);
		throw;
	}

}

// ### FirstOrNull
public static T FirstOrNull(this IQueryable iQ, System.Linq.Expressions.Expression> predicate) where T : class
{
	var res = iQ.FirstOrDefault(predicate);

	return res == default(T) ? null : res;
}
public static T FirstOrNull(this IQueryable iQ) where T : class
{
	var res = iQ.FirstOrDefault();

	return res == default(T) ? null : res;
}

public static IOrderedQueryable OrderBy(this IQueryable iQ, System.Linq.Expressions.Expression> predicate, bool isDescending)
	where T : class
{
	return isDescending ? iQ.OrderByDescending(predicate) : iQ.OrderBy(predicate);
}

/// <summary>
/// Multiple elements encountered on IQueryable.Single ... ()
/// This exception encapsulates System.InvalidOperationException: Sequence contains more than one element
/// </summary>
public class MultipleOnSingleEx : Exception
{
	public MultipleOnSingleEx(SerializationInfo info,
		StreamingContext context) : base(info, context)
	{
	}
	public MultipleOnSingleEx(string message,
		Exception innerException) : base(message, innerException)
	{
	}
	public MultipleOnSingleEx(string message) : base(message)
	{
	}
	public MultipleOnSingleEx()
	{
	}
}

IQueryable .OrderBy( predicate , bool isDescending)

Why such a feature is usefull ?
Because you don’t need two if(..) .. else … branches based on ascending / descending parameter if it’s runtime dynamic (ex.: based on user action).
It’s ever more important when dynamically constructing large queries.

public static IOrderedQueryable OrderBy(this IQueryable iQ, System.Linq.Expressions.Expression> predicate, bool isDescending)
	where T : class
{
	return isDescending ? iQ.OrderByDescending(predicate) : iQ.OrderBy(predicate);
}

Hope it helps a bit in your work.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s