EF 6从SQL View

时间:2018-03-08 13:42:20

标签: c# entity-framework linq asp.net-core backend

更新:问题解决:

所以我设法解决了这个问题。之前我无法获得任何数据的原因是因为EF试图访问一个名为“NodeView”的表,但是没有这样的表但是视图因此没有结果。 这就是为什么我这样做的

 var test = _context.NodeView.FromSql("SELECT * FROM dbo.nodeIcons");
 var nodes = from n in test
             where n.Rootid == 1
             orderby n.Parentid, n.Lvl, n.Position ascending
             select new TreeNode()

我现在直接访问视图,然后根据该结果创建TreeNode对象

我在使用Entity Framework 6从SQL视图访问数据时遇到此问题,但无法找到解决方案。

我在做什么?:

我目前正在使用带有EF 6和Angular 5的.NET Core开发树视图。

这就是我的后端目前的样子

查看模型

public class NodeView
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Descr { get; set; }
    public int Rootid { get; set; }
    public int Parentid { get; set; }
    public int? Lvl { get; set; }
    public int? Position { get; set; }
    public string Expanded { get; set; }
    public string Collapsed { get; set; }
    public string DefIcon { get; set; }
}

节点模型

    public partial class Node
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Descr { get; set; }
    public int Rootid { get; set; }
    public int Parentid { get; set; }
    public int? Lvl { get; set; }
    public int? Position { get; set; }
}

的DbContext

    public partial class NodeContext : DbContext
{
    public virtual DbSet<Node> Node { get; set; }
    public virtual DbSet<NodeView> NodeView { get; set; }

    public NodeContext(DbContextOptions<NodeContext> options) : base(options)
    {

    }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Node>(entity =>
        {
            entity.ToTable("node");

            entity.Property(e => e.Id)
                .HasColumnName("ID")
                .ValueGeneratedNever();

            entity.Property(e => e.Descr)
                .IsRequired()
                .HasColumnName("DESCR")
                .HasMaxLength(256)
                .IsUnicode(false);

            entity.Property(e => e.Lvl).HasColumnName("LVL");

            entity.Property(e => e.Name)
                .IsRequired()
                .HasColumnName("NAME")
                .HasMaxLength(256)
                .IsUnicode(false);

            entity.Property(e => e.Parentid).HasColumnName("PARENTID");

            entity.Property(e => e.Position).HasColumnName("POSITION");

            entity.Property(e => e.Rootid).HasColumnName("ROOTID");
        });

        modelBuilder.Entity<NodeView>(entity => { entity.HasKey(e => e.Id); });
    }
}

在我的控制器中,我正在创建此DTO类的treenode对象

public class TreeNode
{
    public string Label { get; set; }
    public string Data { get; set; }
    public string ExpandedIcon { get; set; }
    public string CollapsedIcon { get; set; }
    public List<TreeNode> Children { get; set; }
    public int ParentId { get; set; }
    public int RootId { get; set; }
    public int Level { get; set; }
    public int Position { get; set; }
    public int ID { get; set; }
    public string Icon { get; set; }

    public TreeNode()
    {
    }


    public void AddChild(TreeNode child)
    {
        if(Children == null)
        {
            Children = new List<TreeNode>();
        }
        Children.Add(child);
    }
}

我的前端需要特定的数据结构。目前,我正在我的控制器中创建它

[HttpGet]
    public List<TreeNode> GetNodes()
    {
        var nodes = from n in _context.NodeView
                    where n.Rootid == 1
                    orderby n.Parentid, n.Lvl, n.Position ascending
                    select new TreeNode()
                    {
                        ID = n.Id,
                        Label = n.Name,
                        Data = n.Descr,
                        ExpandedIcon = n.Expanded,
                        CollapsedIcon = n.Collapsed,
                        Icon = n.DefIcon,
                        RootId = n.Rootid,
                        ParentId = n.Parentid,
                        Level = n.Lvl.Value,
                        Position = n.Position.Value
                    };

        Dictionary<int,TreeNode> parentDict = new Dictionary<int, TreeNode>();
        List<TreeNode> rootTree = new List<TreeNode>();

        foreach (TreeNode aNode in nodes)
        {
            if(aNode.ParentId == 0)
            {
                parentDict.Add(aNode.ID, aNode);
                rootTree.Add(aNode);
            }
            else
            {
                TreeNode fatherNode = parentDict[aNode.ParentId];
                fatherNode.AddChild(aNode);
                parentDict.Add(aNode.ID, aNode);
            }
        }
        return rootTree;
    }

我创建了一个列表节点,并从我的视图中添加了我的所有数据 NodeView

之后我会浏览该列表并查找每个节点的子节点/父节点。

ParentID == 0 是根节点。树的第一个节点。其他所有东西都是子节点,也许也是父节点。在else子句中找到一个孩子后,我正在寻找它的父亲并将其添加到parentDict中。最后,我将整个树返回rootTree。

使用我的节点模型可以正常工作。但它不适用于* NodeView Model **

错误消息:无效的对象名称:NodeView

我真的不知道导致这个问题的原因但是我相信它在DBContext的某处,我在底部创建了第二个模型构建器函数 NodeView ,或者我选择了在我的LINQ语句中查看返回零对象,因此我无法在foreach循环中进行迭代。

=&GT;程序在foreach循环开始时停止

1 个答案:

答案 0 :(得分:0)

所以我设法解决了这个问题。之前我无法获得任何数据的原因是因为EF试图访问名为&#34; NodeView&#34;但是没有这样的表,但是没有结果。这就是为什么我这样做的

 var test = _context.NodeView.FromSql("SELECT * FROM dbo.nodeIcons");
 var nodes = from n in test
             where n.Rootid == 1
             orderby n.Parentid, n.Lvl, n.Position ascending
             select new TreeNode()

我现在直接访问视图,然后根据该结果创建TreeNode对象