如何从存储过程中检索对象树?

时间:2018-02-07 19:07:05

标签: sql-server entity-framework-6 ef-code-first

我想在存储过程中进行计算,其中包括一些聚合,以减少发送回调用者的数据量。鉴于结构:

CREATE TABLE Parent
(
    ParentID int NOT NULL PRIMARY KEY,
    A1 int NOT NULL
)

CREATE TABLE Child
(
    ChildID int NOT NULL PRIMARY KEY,
    ParentID int NOT NULL,
    Expected int NOT NULL,
    CONSTRAINT FK_Child_Parent FOREIGN KEY (ParentID) REFERENCES Parent (ParentID)
)

CREATE TABLE Grandchild
(
    GrandchildID int NOT NULL PRIMARY KEY,
    ChildID int NOT NULL,
    Actual int NOT NULL,
    CONSTRAINT FK_Grandchild_Child FOREIGN KEY (ChildID) REFERENCES Child (ChildID)
)

和存储过程

CREATE PROC testCounts AS
WITH TotalActual AS
(
    SELECT ChildID, SUM(Actual) AS Actual
    FROM Grandchild
    GROUP BY ChildID
)
SELECT ParentID, A1, ChildID, Expected - SUM(Actual) AS Variance
FROM Parent
INNER JOIN Child ON Parent.ParentID = Child.ParentID
INNER JOIN TotalActual ON Child.ChildID = TotalActual.ChildID

我希望能够创建一个包含许多Parent个对象的ChildVariance类型的对象树。实体框架是否能够做到这一点?

到目前为止,我已定义:

public class Parent
{
    public Parent()
    {
        ChildVariances = new HashSet<ChildVariance>();
    }

    [Key]
    public int ParentID { get; set; }
    public int A1 { get; set; }
    public virtual ICollection<ChildVariance> ChildVariances { get; set; }
}

public class ChildVariance
{
    [Key]
    public int ChildID { get; set; }

    public int Variance { get; set; }
    public virtual Parent Parent { get; set; }
}

// In my dbContext
public virtual DbSet<Parent> Parents { get; set; }    

override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Parent>
        .HasMany(e => e.ChildVariances)
        .WithRequired(e => e.Parent)
        .HasForeignKey(e => e.ParentID);
}

// In an access method

var results = Parents.SqlQuery("testCounts");

检查results,我得到父行数乘以子行数。 Parent对象的Childs集合中没有条目。

这样做,我得到了代理对象。也就是说,调试器将类名显示为{System.Data.Entity.DynamicProxies.Parent_C553E08E8B955294BB6673459018EE9B5A7FCB3DF260DEC0B7A10621F4560409}。如果我改为ParentChildVariancesealed,我就不会获得代理对象,但它仍然不起作用。

实体框架实际上可以用这种方式从单个结果集构造一个对象树吗?如果是,我该如何配置呢?

1 个答案:

答案 0 :(得分:0)

这并没有完全回答这个问题,但我能够通过视图而不是存储过程来解决我的实际问题。我不需要多个查询步骤,只需一个查询。

CREATE VIEW ChildVariance AS
WITH TotalActual AS
(
    SELECT ChildID, SUM(Actual) AS Actual
    FROM Grandchild
    GROUP BY ChildID
)
SELECT ParentID, ChildID, Expected, Expected - SUM(Actual) AS Variance
FROM Child
INNER JOIN TotalActual ON Child.ChildID = TotalActual.ChildID

然后我可以将ChildVariance映射为表格:

public class ChildVariance
{
    [Key]
    public int ChildID { get; set; }

    public int ParentID { get; set; }

    public int Expected { get; set; }
    public int Variance { get; set; }
    public virtual Parent Parent;
}

然后我只访问Parent.ChildVariances导航属性来加载数据。为了在同一批次中检索它们,我只需将.Include("ChildVariances")添加到查询中。