Currently i am using a combination of switch operations to generate a linq query, and i am thinking the code is a little bloated.
Is there any way to optimize this code, maybe someway to dynamically build it?
public string[] GetPeopleAutoComplete(string filter, int maxResults, string searchType, string searchOption)
{
var query = from people in _context.People select people;
switch (searchOption)
{
case "StartsWith":
switch (searchType)
{
case "IdentityCode":
query = query.Where(o => o.IdentityCode.StartsWith(filter));
return query.Select(o => o.IdentityCode).Take(maxResults).ToArray();
case "Firstname":
query = query.Where(o => o.Firstname.StartsWith(filter));
return query.Select(o => o.Firstname).Distinct().Take(maxResults).ToArray();
case "Surname":
query = query.Where(o => o.Surname.StartsWith(filter));
return query.Select(o => o.Surname).Distinct().Take(maxResults).ToArray();
}
break;
case "EndsWith":
switch (searchType)
{
case "IdentityCode":
query = query.Where(o => o.IdentityCode.EndsWith(filter));
return query.Select(o => o.IdentityCode).Take(maxResults).ToArray();
case "Firstname":
query = query.Where(o => o.Firstname.EndsWith(filter));
return query.Select(o => o.Firstname).Distinct().Take(maxResults).ToArray();
case "Surname":
query = query.Where(o => o.Surname.EndsWith(filter));
return query.Select(o => o.Surname).Distinct().Take(maxResults).ToArray();
}
break;
case "Contains":
switch (searchType)
{
case "IdentityCode":
query = query.Where(o => o.IdentityCode.Contains(filter));
return query.Select(o => o.IdentityCode).Take(maxResults).ToArray();
case "Firstname":
query = query.Where(o => o.Firstname.Contains(filter));
return query.Select(o => o.Firstname).Distinct().Take(maxResults).ToArray();
case "Surname":
query = query.Where(o => o.Surname.Contains(filter));
return query.Select(o => o.Surname).Distinct().Take(maxResults).ToArray();
}
break;
}
return query.Select(o => o.IdentityCode).Take(maxResults).ToArray();
}
This is exactly where dynamically building expressions is useful:
This doesn’t solve your default case, but that should be relatively easy to add. Also, using reflection like this might be slow, so you might want to cache the results of
GetProperty()andGetMethod().Another thing to note is that the part that chooses whether to use
Distinct()still depends on the property names, but maybe you have a better condition for that (or you could use attributes on the properties).And the two helper methods don’t need to know anything about
Person, so it would be trivial to make them generic.