实体框架:我不明白EntityCollection.Attach和EntityReference.Attach的目的

时间:2011-11-15 19:25:48

标签: entity-framework-4

ObjectContext.AttachObjectSet.Attach用于将分离的实体(已存在于数据库中)附加到上下文 - 这样在调用 ObjectContext.SaveChanges 时,EF不会尝试为此附加实体发送插入命令

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

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

谢谢

1 个答案:

答案 0 :(得分:1)

例如,如果您在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过滤类型。在以下代码中,附加是 与EntityReference一起使用,它不会占用IQueryable。相反,你需要 传入一个对象,您可以使用FirstOrDefault查询方法获取该对象。以来 如果您尝试传入null,Attach将抛出异常,您需要测试null 在调用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);
}

使用此代码,只会加载客户。