实体框架4.1:如何在创建新实体后访问虚拟实体属性?

时间:2011-03-26 19:23:58

标签: c# entity-framework entity-framework-ctp5 entity-framework-4.1

这是我的简化代码:

// Domain models
public class Order
{
    public int ID { get; set; }
    public int CustomerID { get; set; }
    public virtual ICollection OrderLineItems { get; set; }
    public virtual ICollection Transactions { get; set; }

    public void CreatePurchaseDebit()
    {
        var purchaseDebit = new Transaction()
        {
            Amount = OrderLineItems.Select(x => x.Product)
                         .Sum(x => x.Price) * -1
        };
        Transactions.Add(purchaseDebit);
    }
}

public class OrderLineItem
{
    public int ID { get; set; }
    public int OrderID { get; set; }
    public int ProductID { get; set; }
    public virtual Product Product { get; set; }
}

public class Product
{
    public int ID { get; set; }
    public decimal Price { get; set; }
}

// Repository
public class Repository
{
    public void Add(Order order)
    {
        context.Add(order);
        order.CreatePurchaseDebit(); // This throws an error
    }
}

此处的问题是,尝试执行CreatePurchaseDebit() Productnull即使在创建过程中用户已相应设置了ProductID

我希望将新Order添加到DbContext会通过关联的外键ID填充虚拟域模型属性。在调试器中,我可以看到Order有多个OrderLineItems,并且每个OrderLineItem都有一个有效ProductID,但是Productnull所以我无法访问Product的价格!

那么有没有办法告诉Entity Framework填充虚拟域模型属性还是我的设计不好?

PS:即使我在添加新订单到DbContext SaveChanges()之后调用Product仍然是null。我想在调用Order之前确保SaveChanges()有购买借记卡,这样订单就无法在没有交易的情况下存在。

谢谢!

1 个答案:

答案 0 :(得分:1)

仅因为您设置ProductId而无法加载产品。如果您创建新的Order并且希望在产品中填充订单行项目,请使用产品ID从数据库加载产品并将其分配给订单行项目。

所以不要这样做:

var order = new Order
  {
    CustomerId = customerId,
    OrderLineItems = new List<OrderLineItme>
      {
        new OrderLineItem
          {
            ProductId = productId
          }
      }
  };

使用它:

var product = context.Products.Single(p => p.Id == productId);
var order = new Order
  {
    CustomerId = customerId,
    OrderLineItems = new List<OrderLineItme>
      {
        new OrderLineItem
          {
            Product = product
          }
      }
  };