I have a table of elements that can be associated to each other (within the same table).
So for example a structure like:
[Id] Int
[ParentWithinThisTableId] Int
[AFieldToQueryAgainst] NVarCharMax
At the beginning of the search, I will be given a string query and a single Id (call it StartId
that points to an element in this table. What I want to do is compare the string query to the [AFieldToQueryAgainst]
on the element at the Id given, but also query against the same column for all rows that have [ParentWithinThisTableId] == StartId
and then all of the rows that have these ids as [ParentWithinThisTableId]
.
The only way I can think to do it is recursively like:
var forms = db.Forms.Where(m => m.ParentWithinThisTableId == this.Id);
var searchMatches = new List<Form>();
foreach (var form in forms)
{
forms = forms.Concat(AddSearches(query, form.Id));
}
foreach (var form in forms)
{
if (form.AFieldToQueryAgainst.Contains(query))
{
searchMatches.Add(form);
}
}
With AddSearches
being recursive like:
private IQueryable<Form> AddSearches(string query, int startId)
{
var items = RepositoryProxy.Context.Forms.Where(m => m.ParentWithinThisTableId == startId);
foreach (var item in items)
{
items = items.Concat(AddSearches(query, item.Id));
}
return items;
}
But this takes about 1.8 seconds run time in my testing on a relatively shallow tree. Is there a more efficient way to do this? Possibly avoid iterating each of the IQueryables
until they're all compiled somehow?