DbContext.Set <t>()。SqlQuery加载相关实体</t>

时间:2014-12-16 09:07:38

标签: c# .net entity-framework

我正在运行以下代码:

var paramUserId = new SqlParameter
{
    ParameterName = "userId",
    Value = userId
};

string query = string.Format("{0} {1}",
              "usp_GetItems",
              "@userId");

var results = _context.Set<Item>().SqlQuery(query, paramUserId);

usp_GetItems是我拥有的存储过程。 但是我的导航属性没有被加载。反正有没有在Entity Framework上实现这个?

因为根据这个问题,Eager loading in EntityFramework with DbContext.Database.SqlQuery看起来很可能。

由于

1 个答案:

答案 0 :(得分:1)

假设存储过程返回ItemsUsers的非规范化,我想到的一个想法是使用投影DTO,它模仿存储过程结果的结构,然后到使用SqlQuery的{​​{1}}风格投射到展平的DTO中。

然后,您可以使用LINQ再次将结果集重新规范化回实体图表,我认为这是初衷。

详情

假设您的EF模型中存在实体:

public class Item
{
    public int ItemId { get; set; }
    public string Name { get; set; }
}

public class User
{
    public int UserId { get; set; }
    public string Name { get; set; }
    public ICollection<Item> Items { get; set; }
}

创建一个转移DTO,它代表Stored Proc结果集的展平结构:

public class UserItemProcDto
{
    public int ItemId { get; set; }
    public string ItemName { get; set; }
    public int UserId { get; set; }
    public string UserName { get; set; }
}

然后投射到非规范化的DTO,最后使用LINQ重新规范化:

var results = _context.SqlQuery<UserItemProcDto>(query, paramUserId);

var usersWithItems = results.GroupBy(r => r.UserId)
    .Select(g => new User
    {
        UserId = g.Key,
        Name = g.First().UserName,
        Items = g.Select(i => new Item
        {
            ItemId = i.ItemId,
            Name = i.ItemName
        }).ToList()
    });

对于许多跨越多个表的存储过程来说,这显然不是你想做的事情,当然:)