Is recursive query possible in LINQ to Entities

前端 未结 3 1770
感动是毒
感动是毒 2020-12-10 07:28

this is my first question and sorry about my weak language.

I\'ve got a table like this model;

 public class Menu
 {
      [Key]
      public int ID          


        
3条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-10 08:15

    LINQ to Entities does not support recursive queries.

    However, loading the whole tree stored in a database table is easy and efficient. There seem to be some myths from earlier version of Entity Framework, so let's demystify them.

    All you need is to create a proper model and FK relationship:

    Model:

    public class Menu
    {
        public int ID { get; set; }
        public int? ParentID { get; set; }
        public string MenuName { get; set; }
        public int OrderNo { get; set; }
        public bool isDisplayInMenu { get; set; }
    
        public ICollection Children { get; set; }
    }
    

    Fluent configuration:

    modelBuilder.Entity()
        .HasMany(e => e.Children)
        .WithOptional() // EF6
        .WithOne() // EF Core
        .HasForeignKey(e => e.ParentID);
    

    The important change is that in order to setup such relationship, ParentID must be nullable, and root items should use null instead of 0.

    Now, having the model, loading the whole tree is simple as that:

    var tree = db.Menu.AsEnumerable().Where(e => e.ParentID == null).ToList();
    

    With AsEnumerable() we ensure that when the query is executed, the whole table will be retrieved in memory with a simple non recursive SELECT SQL. Then we simply filter out the root items.

    And that's all. At the end we have a list with root nodes with their children, grand children etc. populated!

    How it works? No lazy, eager or explicit loading is needed/used. The whole magic is provided by the DbContext tracking and navigation property fix up system.

提交回复
热议问题