简体   繁体   中英

How can I efficiently query against a tree structure stored in a database using Entity Framework?

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?

why can't you just use a self join ?

var these = (from p in items
                join x in items on p.Id equals x.ParentId
                where x != null
                select x).ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM