实体框架:我不理解EntityCollection的目的.Attach和EntityReference.Attach



ObjectContext.AttachObjectSet.Attach用于将一个分离的实体(已经存在于DB中)附加到上下文中-当ObjectContext时采用这种方式。SaveChanges被调用时,EF不尝试为这个附加的实体发送插入命令

但是我不理解EntityCollection.AttachEntityReference.Attach的目的。也就是说,这两种方法只能附加已经由ObjectContext管理的实体(因此它们不能用于附加EntityState设置为AddedDetached的实体)。

由于由ObjectContext管理的实体已经自动解决了它们的关系(即它们的EntityReference属性返回一个父实体,它们的EntityCollection属性包含相关的子实体),我无法理解通过使用EntityCollection.AttachEntityReference.Attach将相关实体E1附加到特定实体E2,我们究竟会获得什么,因为E1已经由ObjectContext自动附加到E2 ?

谢谢

作为一个例子,如果您在ObjectContext中有一个客户,并且您想要获得它客户的预订,您可以拨打以下电话:

myCust.Reservations.Load()

这将加载该客户的所有预订。但是,如果您想过滤这些预订,您可以在-中使用CreateSourceQuery相反,如下面的代码所示:

var customer=context.Contacts.OfType<Customer>().First();
var sourceQuery = customer.Reservations.CreateSourceQuery()
                    .Where(r => r.ReservationDate > new DateTime(2008, 1, 1));
customer.Reservations.Attach(sourceQuery);

该查询将在调用Attach方法时执行。现在,只有该客户的预订子集将从数据库中检索并具体化为对象。

你也可以使用CreateSourceQuery来筛选类型。在下面的代码中,Attach是与EntityReference一起使用,它不会接受IQueryable。相反,你需要传入一个对象,您可以使用FirstOrDefault查询方法获得该对象。自如果您尝试传入空值,Attach将抛出异常,您需要测试空值在调用Attach之前:

var addresses = context.Addresses.Take(5);
foreach (var a in addresses)
{
  var sq = a.ContactReference.CreateSourceQuery()
            .OfType<Customer>().FirstOrDefault();
  if (sq != null)
    a.ContactReference.Attach(sq);
}

在此代码中,只加载客户。

最新更新