c# - DbContext.Set<T>().SqlQuery 加载相关实体

标签 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看起来这是可能的。

谢谢

最佳答案

假设存储过程返回 Items 的非规范化和 Users ,想到的一个想法是使用一个模拟存储过程结果结构的投影 DTO,然后使用 Context.Database.SqlQuery<T> 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()
    });

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

关于c# - DbContext.Set<T>().SqlQuery 加载相关实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27500989/

相关文章:

C# 静态方法里面的变量是一开始就初始化还是在方法第一次调用的时候初始化?

c# - vNext : Referencing non-vNext projects

c# - Automapper 和 MvcPager3 协同工作

c# - 如何设置字符串属性 C# EF 的分隔词的最大长度

entity-framework - 如何指定包含在 Entity Framework 中的位置

c# - DateTime.ToString() 不能按预期使用斜杠作为日期分隔符

c# - 从分数中设置高分并在unity2D游戏中显示

c# - 屏幕阅读器阅读禁用按钮的 AutomationProperty.Id

.net - PaintEventArgs.ClipRectangle 和 PaintEventArgs.Graphics.ClipBounds 有什么区别

asp.net - runAllManagedModulesForAllRequests = "true"在 IIS7 中终止 Windows 身份验证