我正在运行以下代码:
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看起来很可能。
由于
答案 0 :(得分:1)
假设存储过程返回Items
和Users
的非规范化,我想到的一个想法是使用投影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()
});
对于许多跨越多个表的存储过程来说,这显然不是你想做的事情,当然:)