I'm trying to select several rows from a table but would like the selection to stop if the first where clause comes back with results. Basically if there are results with language then I don't need to query for DevLanguage or FallbackLanguage, is this possible in a single query with || operator or with some other LINQ magic?
var languageStrings = _presentationContext.LocalizationStrings .Where(x => x.Namespace.Namespace == @namespace && x.Namespace.Language == language); var devStrings = _presentationContext.LocalizationStrings .Where(x => x.Namespace.Namespace == @namespace && x.Namespace.Language == Constants.DevLanguage); var fallbackStrings = _presentationContext.LocalizationStrings .Where(x => x.Namespace.Namespace == @namespace && x.Namespace.Language == Constants.FallbackLanguage); var localizationStrings = languageStrings.Any() ? languageStrings : devStrings.Any() ? devStrings : fallbackStrings.Any() ? fallbackStrings
CodePudding user response:
While there are probably more downsides to the code below than I know of, it's a one-liner (if you ignore the temp variable declaration) and only executes the LINQ queries if the previous one failed to return any results.
IEnumerable<dynamic> temp;
var localizationStrings =
(temp = _presentationContext.LocalizationStrings.Where(x =>
x.Namespace.Namespace == @namespace &&
x.Namespace.Language == language)).Any() ? temp :
(temp = _presentationContext.LocalizationStrings.Where(x =>
x.Namespace.Namespace == @namespace &&
x.Namespace.Language == Constants.DevLanguage)).Any() ? temp :
(temp = _presentationContext.LocalizationStrings.Where(x =>
x.Namespace.Namespace == @namespace &&
x.Namespace.Language == Constants.FallbackLanguage)).Any() ? temp :
Enumerable.Empty<string>();
One reason why I would either pick your original code or search for a different method is because assigning values in a chain like this is not performance friendly.
CodePudding user response:
I would put the common part of these queries into a separate query.
var query = _presentationContext.LocalizationStrings.Where(x => x.Namespace.Namespace == @namespace);
var languageStrings = query.Where(x => x.Namespace.Language == language);
var devStrings = query.Where(x => x.Namespace.Language == Constants.DevLanguage);
var fallbackStrings = query.Where(x => x.Namespace.Language == Constants.FallbackLanguage);
The SQL is generated the same.
If you need to minimize the number of roundtrips then the code may look like this.
var query = _presentationContext.LocalizationStrings.Where(x => x.Namespace.Namespace == @namespace);
var languageStrings = query.Where(x => x.Namespace.Language == language);
var devStrings = query.Where(x => x.Namespace.Language == Constants.DevLanguage);
var fallbackStrings = query.Where(x => x.Namespace.Language == Constants.FallbackLanguage);
IQueryable<Localization> localizationStrings = null;
if (languageStrings.Any())
localizationStrings = languageStrings;
else if (devStrings.Any())
localizationStrings = devStrings;
else if (fallbackStrings.Any())
localizationStrings = fallbackStrings;