使用原始sql查询加载导航属性

时间:2015-08-17 16:04:42

标签: c# entity-framework-6

我有这个SQL查询:

SELECT 
    t.ServerId, t.Id, s.Name
FROM 
    MyTable as t
JOIN 
    Server s ON t.ServerId = S.Id

我正在运行它:

context.Database.SqlQuery<entity>("query_goes_here");

如何配置EF以便它使用查询中的返回数据加载我的实体的Server属性?

基于@octavioccl的回答,我最终做到了这一点:

foreach(var result in results)
{
    context.Attach(result);
    context.Entry(result).Reference(p => p.Server).Load();
}

但是我担心这会造成很多数据库访问?

2 个答案:

答案 0 :(得分:6)

对返回实体类型的查询使用DbSet.SqlQuery方法。返回的对象必须是DbSet对象所期望的类型,并且它们将由数据库上下文自动跟踪,除非您关闭跟踪。

var enties= _context.Entities.SqlQuery("query_goes_here");

执行查询后,您应该可以通过延迟加载通过Server实例获取entity

var server=entity.Server;

另一方面,Database.SqlQuery返回的数据不会被数据库上下文跟踪,即使您使用此方法检索实体类型也是如此。如果要跟踪使用此方法执行查询后获得的实体,可以尝试以下操作:

//Attach the entity to the DbContext
_context.Entities.Attach(entity);

//The Server navigation property will be lazy loaded
var server=entity.Server;

如果您已禁用延迟加载,则可以使用DbEntityEntry.Reference()方法明确加载导航属性:

//Load the Server navigation property explicitly
_context.Entry(entity).Reference(c => c.Server).Load(); 

答案 1 :(得分:0)

您可以先加载导航属性的所有行,然后再加载主实体。如果需要,请先对其应用过滤器。

var servers = context.Servers.Where(m => m.ServerType == "Windows").ToList();
var mytable = context.MyTables.ToList();

或使用SqlQuery

var servers = context.Database.SqlQuery<Server>("query_goes_here");

foreach (var serv in servers)
    context.Servers.Attach(serv);

然后查询MyTable和EF将为您将两者链接在一起