简体   繁体   中英

Entity Framework - change from table to tree structure

I'm rather new with Entity Framework and I'm trying to convert a table into the tree structure with code first and publish it with OData.

This is my db table:

-----------------------------------------------------------
| id | text        | href         | selectable | parentId |
|---------------------------------------------------------|
|  0 | MES         | NULL         | 0          | NULL     |
|  1 | Login       | #/login      | 1          | 0        |
|  2 | Quality     | NULL         | 0          | 0        |
|  3 | Task List   | #/taskList   | 1          | 2        |
|  4 | Result List | #/resultList | 1          | 2        |
-----------------------------------------------------------

What I need is followin JSON:

var tree = [
    {
        text: "MES",
        selectable: false,
        nodes: [
        {
            text: "Login",
            href: "#/login",
            selectable: true
        },
        {
            text: "Quality",
            selectable: false,
            nodes: [
            {
                text: "Task List",
                href: "#/taskList",
                selectable: true
            }, {
                text: "Result List",
                href: "#/resultList",
                selectable: true
            }]
        }]
    }];

For that I have prepared the model:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace AtslMde5Service.Models
{
    [Table("SiteMap")]
    public class SiteMapConfigurationItem
    {
        [Key]
        [Column("id")]
        public int Id { get; set; }
        [Column("text")]
        public string Text { get; set; }
        [Column("href")]
        public string Href { get; set; }
        [Column("selectable")]
        public bool Selectable { get; set; }
        [Column("parentId")]
        public int? ParentId { get; set; }

        public virtual ICollection<SiteMapConfigurationItem> ChildNodes { get; set; }
    }
}

and the controller

using AtslMde5Service.Models;
using System.Linq;
using System.Web.Http;
using System.Web.Http.OData;

namespace AtslMde5Service.Controllers.OData
{
    public class SiteMapConfigurationItemsController : ODataController
    {
        private GlobalContext db = new GlobalContext();

        [EnableQuery]
        public SingleResult<SiteMapConfigurationItem> GetSiteMapConfigurationItems()
        {
            return SingleResult.Create(db.SiteMapConfigurationItems.Where(siteMapConfigurationItem => siteMapConfigurationItem.ParentId == null));
        }
    }
}

This is my GlobalContext class:

using AtslMde5Service.Models.ATSL_MDE;
using System.Data.Entity;

namespace AtslMde5Service.Models
{
    public class GlobalContext : DbContext
    {
        public GlobalContext()
            : base("name=GlobalContext")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<SiteMapConfigurationItem>().HasMany(k => k.ChildNodes);

            modelBuilder.Entity<SiteMapConfigurationItem>().Map(m =>
            {
                m.MapInheritedProperties();
            });
        }

        public DbSet<SiteMapConfigurationItem> SiteMapConfigurationItems { get; set; }
    }
}

Unfortunately what I get returned back is just the first node, I don't know how to link Id and Parent Id.

Thanks for any help.

Add to your object:

public virtual SiteMapConfigurationItem Parent { get; set; }

Then change this:

modelBuilder.Entity<SiteMapConfigurationItem>().HasMany(k => k.ChildNodes);

to this:

modelBuilder.Entity<SiteMapConfigurationItem>().HasMany(k => k.ChildNodes).WithOptional(k => k.Parent).HasForeignKey(k => k.ParentId);

So it knows how to traverse up and down the relationship chain. Now if you have Lazy Loading enabled on your context you should be able to traverse the self referencing foreign key without any problem.

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