C# 实体框架-从表到树结构的更改

C# 实体框架-从表到树结构的更改,c#,asp.net,entity-framework,odata,C#,Asp.net,Entity Framework,Odata,我是实体框架的新手,我尝试先用代码将表转换为树结构,然后用OData发布它 这是我的db表: ----------------------------------------------------------- | id | text | href | selectable | parentId | |---------------------------------------------------------| | 0 | MES | NU

我是实体框架的新手,我尝试先用代码将表转换为树结构,然后用OData发布它

这是我的db表:

----------------------------------------------------------- | 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 | ----------------------------------------------------------- 为此,我准备了模型:

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; }
    }
}
使用System.Collections.Generic;
使用System.ComponentModel.DataAnnotations;
使用System.ComponentModel.DataAnnotations.Schema;
命名空间AtslMde5Service.Models
{
[表格(“网站地图”)]
公共类SiteMapConfigurationItem
{
[关键]
[列(“id”)]
公共int Id{get;set;}
[栏目(“正文”)]
公共字符串文本{get;set;}
[列(“href”)]
公共字符串Href{get;set;}
[列(“可选”)]
公共布尔可选{get;set;}
[列(“父ID”)]
public int?ParentId{get;set;}
公共虚拟ICollection子节点{get;set;}
}
}
和控制器

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));
        }
    }
}
使用AtslMde5Service.Models;
使用System.Linq;
使用System.Web.Http;
使用System.Web.Http.OData;
命名空间AtslMde5Service.Controllers.OData
{
公共类SiteMapConfigurationItemsController:ODataController
{
私有GlobalContext db=新的GlobalContext();
[启用查询]
公共SingleResult GetSiteMapConfigurationItems()
{
返回SingleResult.Create(db.SiteMapConfigurationItems.Where(siteMapConfigurationItem=>siteMapConfigurationItem.ParentId==null));
}
}
}
这是我的GlobalContext课程:

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; }
    }
}
使用AtslMde5Service.Models.ATSL\u MDE;
使用System.Data.Entity;
命名空间AtslMde5Service.Models
{
公共类GlobalContext:DbContext
{
公共GlobalContext()
:base(“name=GlobalContext”)
{
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
modelBuilder.Entity().HasMany(k=>k.ChildNodes);
modelBuilder.Entity().Map(m=>
{
m、 MapInheritedProperties();
});
}
公共数据库集SiteMapConfigurationItems{get;set;}
}
}
不幸的是,返回的只是第一个节点,我不知道如何链接Id和父Id

感谢您的帮助。

添加到您的对象:

public virtual SiteMapConfigurationItem Parent { get; set; }
然后更改此选项:

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

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

因此,它知道如何在关系链上来回移动。现在,如果您在上下文中启用了延迟加载,您应该能够毫无问题地遍历自引用外键。

谢谢您的回答。不幸的是,我仍然得到以下信息:{“value”:[{“Id”:1,“Text”:“MES”,“Href”:null,“可选的”:false,“ParentId”:null},{“Id”:2,“Text”:“Login”,“Href”:“#/Login”,“可选的”:true,“ParentId”:1},{“Id”:3,“Text”:“Quality”,“Href”:null,“可选的”:false,“ParentId”:1},{“Id”:4,“Text”:“任务列表”,“Href”:“#/taskList”,“selective”:true,“ParentId”:3},{“Id”:5,“Text”:“Result List”,“Href”:“#/resultList”,“selective”:true,“ParentId”:3}}”。一定还有一些小东西丢失了。。。
modelBuilder.Entity<SiteMapConfigurationItem>().HasMany(k => k.ChildNodes).WithOptional(k => k.Parent).HasForeignKey(k => k.ParentId);