使用Entity Framework SqlQuery填充子属性

鉴于以下POCO Code First Entities

public class Customer { public int CustomerId { get; set; } public string CustomerTitle { get; set; } public string CustomerFirstName { get; set; } public string CustomerLastName { get; set; } public ICollection Orders { get; set; } } public class Order { public int OrderId { get; set; } ... public int CustomerId { get; set; } public Customer Customer { get; set; } } 

使用linq,您可以使用Include属性获取填写的订单

 var cust = (from cust in context.Customer where cust.CustomerId == 1 select cust) .Include(ord => ord.Orders) .FirstOrDefault(); 

我试图使用paramaterised sql获得相同的结果,使用

  Customer co = context.Customer.SqlQuery( @"select [Customer].[CustomerId], ... [Order].[OrderId] AS [OrderId], ... from Customer join Order on Customer.CustomerId = Order.CustomerId where Customer.CustomerId = @custid", sqlParm) .FirstOrDefault(); 

如何使用上面的命令填充co.Orders中的Orders,似乎我不能在SqlQuery中使用Include语句。 这是一个非常简单的示例,仅用于说明目的,实际查询将更多地涉及。

这根本不可能。 直接SQL执行不提供导航属性的填充,你真的不能使用Include。 您必须执行两个单独的SQL查询才能获得Cutomer及其Orders

我使用了以下类结构作为解决方法:

 public class Customer { public int CustomerId { get; set; } } public class Order { public Customer Customer { get; set; } private int _customerId; private int CustomerId { get { return _customerId; } set { Customer.CustomerId = _customerId = value; } } public Order() { Customer = new Customer(); } } 

在这种情况下,您不需要运行查询两次,并且以下查询将向客户提供订单:

db.Database.SqlQuery(“从Orders ord选择cu.CustomerId,ord.OrderId,在cu.CustomerId = ord.CustomerId上加入Customer cu”)。ToList();

对我有用的是在关闭使用之前访问相关成员。

 public static Customer GetCustomer (int custid) { Customer co = null; using (var context = new YourEntities()) { // your code co = context.Customer.SqlQuery( @"select [Customer].[CustomerId], ... [Order].[OrderId] AS [OrderId], ... from Customer join Order on Customer.CustomerId = Order.CustomerId where Customer.CustomerId = @custid", sqlParm) .FirstOrDefault(); // my addition // cause lazy loading of Orders before closing the using ICollection orders = co.Orders; } // can access co.Orders after return. return (co); }