【问题标题】:DbContext.Set<T>().SqlQuery Loading related entitiesDbContext.Set<T>().SqlQuery 加载相关实体
【发布时间】:2014-12-16 18:49:07
【问题描述】:

我正在运行以下代码:

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 是我拥有的存储过程。 但是我的导航属性没有被加载。无论如何要在实体框架上完成这个?

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

谢谢

【问题讨论】:

标签: c# .net entity-framework


【解决方案1】:

假设存储过程返回 ItemsUsers 的非规范化,我想到的一个想法是使用模拟存储过程结果结构的投影 DTO,然后使用 @987654321将SqlQuery 的@ 风格投射到扁平的 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:

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()
    });

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

【讨论】:

  • 需要注意的一点是,如果有 Item.User 的反向实体导航,您可能需要将其作为第二个离散步骤执行 - AFAIK 在期间无法链接两个引用创作投影。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-23
  • 1970-01-01
  • 1970-01-01
  • 2015-09-21
  • 1970-01-01
  • 2011-04-09
  • 1970-01-01
相关资源
最近更新 更多