I have an Entity Framework Core statement where I need to create a union of multiple selects. The number of selects is variable.
I would like to do something like this, but it is not working:
public List<Valuation> GetValuations(List<GetValuationCriteria> valuationCriteriaList)
{
IQueryable<Valuation> combinedQuery = null;
IQueryable<Valuation> lastQuery = null;
for (int xx = 0; xx < valuationCriteriaList.Count; xx++)
{
var valuationCriteria = valuationCriteriaList[xx];
var selectQuery = DbContext.Valuations
.Where(w => w.ActivityDate == valuationCriteria.ActivityDate &&
w.ValuationSourceId == valuationCriteria.ValuationSourceId &&
w.ActivityTypeId == valuationCriteria.ActivityTypeId &&
w.CurrencyId == valuationCriteria.CurrencyId &&
w.OrganizationHierarchyId == valuationCriteria.OrganizationHierarchyId &&
w.StatusCode == "A");
if (xx == 0)
{
combinedQuery = selectQuery;
lastQuery = combinedQuery;
}
else
{
lastQuery.Concat(selectQuery);
lastQuery = selectQuery;
}
}
var result = combinedQuery.ToList();
return result;
}
My goal is to execute the queries all in one trip to the database via the union. Is there a way to do this?
Unioned query here. All LINQ operators return a new query but this code never uses that. In the endfirstQueryis unchanged. You'd need somethingtotalQuery=totalQuery.Union(query)BUT ... what are you actually trying to do? What are the real queries? EF is an ORM, not a SQL builder. It deals with entities. First, you can't just UNION queries targeting different tables for example. Where would the entity changes go? Second, UNIONs are expensive unless they can be simplified. If you want to query multiple names, you could usenames.Contains(w.Name)to emitName in (@id1,.this? 2)totalQuery=totalQuery.Union(query)will actually produce a UNION, even if it's ineffective. If the partial queries are incompatible ... GOTO 1 - what isthisand what are you actually trying to do? It matters a lot. You may be able to use a simple query instead of whatever you try to use now. Or specify an inheritance relation to load all the things you want at once. We can't guess from the current question - apart from the typo, it has no other information.Concatcreates a newIQueryable. You have to assign the result to something.Concatreturns:combinedQuery=combinedQuery.Concat(selectQuery). What you try to do is equivalent toORthough and doesn't really need aUNION ALL. You could use LINQKit to combine multiple conditions with OR. BUT you should check performance. The query will be slow unless all fields are indexed to begin with. The database may or may not be able to simplify all those conditions in a way that allows all indexes to be used.