Searching based on a query string and returning JSON ActionResult Using a Select2, what's the best way to refactor multiple if statements.

This code returns Json to a select2 based on what information it gets in the query. The action result is used in many places so it has accommodate different parameter being passed.  

public ActionResult *********(string query = "", int? id = null, int? accountId = null)
    {
        var empty = new object();

        if (query == "" &amp;&amp; accountId == null)
        {
            return Json(empty, JsonRequestBehavior.AllowGet);
        }

        if (query == "" &amp;&amp; accountId != null)
        {
            var search = Db.Entities.Find(accountId);
            var suggestions = Db.Entities.Where(
                x =&gt; x.Name.Contains(search.Name) &amp;&amp; x.EntityId != accountId &amp;&amp; !String.IsNullOrEmpty(x.Group.Label))
                .ToList()
                .Select(item =&gt; new { id = item.GroupId, text = item.Group.Label });

            return Json(suggestions, JsonRequestBehavior.AllowGet);

        }

        if (id != null)
        {
            var accountGroup = Db.Groups.Find(id);
            if (accountGroup != null)
                return Json(new { id = accountGroup.GroupId, text = accountGroup.Label },
                    JsonRequestBehavior.AllowGet);
            return Json(null, JsonRequestBehavior.AllowGet);
        }
        var list = Db.Groups.Where(
            r =&gt; !String.IsNullOrEmpty(query) &amp;&amp; query.Length &gt; 2 &amp;&amp; (r.StatusId == GroupStatus.Both || r.StatusId == GroupStatus.Customer) &amp;&amp; r.Label.ToLower().Contains(query.ToLower())).OrderBy(r =&gt; r.Label).Select(item =&gt; new { id = item.GroupId, text = item.Label }).ToList();
        if (!list.Any())
        {
            return Json(new List&lt;object&gt;() { new { id = query, text = query } }, JsonRequestBehavior.AllowGet);
        }
        return Json(list, JsonRequestBehavior.AllowGet);
    }
In following query

var suggestions = Db.Entities.Where(x =&gt; x.Name.Contains(search.Name)
                              &amp;&amp; x.EntityId != accountId
                              &amp;&amp; !String.IsNullOrEmpty(x.Group.Label))
                 .ToList()
                 .Select(item =&gt; new { id = item.GroupId, text = item.Group.Label });


You shouldn't call ToList(). Read this answer from a question on StackOverflow. This is the essential part:


  For example, in an Entity Framework query we can only use a restricted number of methods. So if, for example, we need to use one of our own methods in a query we would typically write something like

   var query = context.Observations.Select(o =&gt; o.Id)
               .AsEnumerable().Select(x =&gt; MySuperSmartMethod(x))

  
  ToList – which converts an IEnumerable to a List – is often used for this purpose as well. The advantage of using AsEnumerable vs. ToList is that AsEnumerable does not execute the query. AsEnumerable preserves deferred execution and does not build an often useless intermediate list.
  
  On the other hand, when forced execution of a LINQ query is desired, ToList can be a way to do that. 




No need to check twice for the query to see if it is empty. Your code would be better like this:

if (query == "")
{
    if (accountId == null)
    {
        //return Json
    }
    else
    {
        //return some other Json
    }
}




You can improve the performance of your LinQ query by building it correctly. First check for the EntityId != accountId, then !String.IsNullOrEmpty(x.Group.Label) and last for x.Name.Contains(search.Name):

var suggestions = Db.Entities.Where(x =&gt; x.EntityId != accountId
                              &amp;&amp; !String.IsNullOrEmpty(x.Group.Label)
                              &amp;&amp; x.Name.Contains(search.Name))
                 .AsEnumerable()
                 .Select(item =&gt; new { id = item.GroupId, text = item.Group.Label });


Notice that I changed ToList to AsEnumerable.



Variable names like list and search are not meaningful. Give clear names to your variables that kind of represent what they are holding.

var list = Db.Groups.Where(...);


would become:

var groups = Db.Groups.Where(...);