级联操作


  当对一个实体的其关联属性或实体集属性进行修改时,Insert / Update 操作时也会将这些修改一起持久化到库里。

1、插入关联实体或实体集

  如,在插入一个 Orders 对象时,可以同时在订单明细集合里添加 OrderDetails 对象。

[TestMethod]
public void TestInsertWithDetails()
{
    var order = new Orders
    {
        OrderDate = DateTime.Now,
        OrderDetailses = new EntitySet<OrderDetails>(),
    };

    //构造5条明细
        
    for (var i = 0; i < 5; i++)
    {
        order.OrderDetailses.Add(new OrderDetails
        {
            ProductID = 1 + i,
            UnitPrice = 0.3,
            Quantity = 12,
            Discount = 0.99,
        });
    }

    using (var db = new DbContext())
    {
        db.Orders.Insert(order);
    }
}

  OrderDetails 对象的 OrderID 属性值是无法预知的,只有 Orders 对象新增后,自动赋给每一个 OrderDetails 对象。


2、更新关联实体

  更新一个实体的同时,可以对其关联的实体进行更新。

  如下例中,更新订单明细的同时,对订单的数据进行更新。

[TestMethod]
public void TestUpdateReference()
{
    using (var db = new DbContext())
    {
        var detail = db.OrderDetails.FirstOrDefault();
        detail.Orders.ShipName = "fireasy";
                
        db.OrderDetails.Update(detail);
    }
}

  同理,Update 也可同时更新子实体集中的部分实体的属性。

[TestMethod]
public void TestUpdateChildCollection()
{
    using (var db = new DbContext())
    {
        var order = db.Orders.FirstOrDefault();

        if (order.OrderDetailses.Count > 0)
        {
            order.OrderDetailses[0].Products.UnitsInStock = 45;
        }

        db.Orders.Update(order);
    }
}

3、更新实体集

  更新一个实体的同时,可以对其子实体集进行更新。这些操作是在事务中完成的,所以你不必须担心数据的一致性问题。

  比如下例中,在更新订单的同时,将订单明细中的第一项移除。在执行 Update 的同时,订单明细的第一条数据也会被删除。

[TestMethod]
public void TestRemoveDetail()
{
    using (var db = new DbContext())
    {
        var order = db.Orders.Get(11092);

        order.OrderDetailses.RemoveAt(0);

        db.Orders.Update(order);
    }
}

  当然,也可以在移除订单明细的同时,往子实体集中添加新的订单明细,或对实体集中的某一实体进行修改,等同于上节中的更新。如下例:

[TestMethod]
public void TestRemoveAndAddDetail()
{
    using (var db = new DbContext())
    {
        var order = db.Orders.Get(11092);

        order.OrderDetailses.RemoveAt(0);
        order.OrderDetailses.Add(new OrderDetails { ProductID = 1 });

        db.Orders.Update(order);
    }
}

  如果对子实体集 Clear 或设为 null,那么将移除所有的订单明细。如下例:

[TestMethod]
public void TestClearDetail()
{
    using (var db = new DbContext())
    {
        var order = db.Orders.Get(11092);

        order.OrderDetailses = null;

        db.Orders.Update(order);
    }
}