使用Entity Framework SqlQuery填充子属性

时间:2011-10-19 13:30:20

标签: c# entity-framework-4.1

鉴于以下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<Order> 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语句。这是一个非常简单的示例,仅用于说明目的,实际查询将更多参与。

3 个答案:

答案 0 :(得分:13)

根本不可能。直接SQL执行不提供导航属性的填充,您实际上不能使用Include。您必须执行两个单独的SQL查询才能获得Cutomer和她的Orders

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

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<Order> orders = co.Orders;

    }

    // can access co.Orders after return.
    return (co);
}