如何保存来自不同DBContext CTP5的相关新对象

时间:2011-03-04 11:08:06

标签: entity-framework-ctp5

我正在研究MVC3应用程序,我使用DbContext代码生成器从我的数据库创建了我的POCO类。一切顺利,直到我遇到这种情况。请注意,我使用存储库模式,并且我为每个实体使用专用存储库,无论是获取DbContext的新实例。

现在,我处于这种情况:

对象A与B具有一对多的关系(A可以有一个或多个B) 对象B与C具有多对一的关系(C可以有一个或多个B) 对象B与D具有多对一的关系(D可以有一个或多个B)

我应该添加一个新对象B,考虑到对象C和D尚未存在,所以我必须只做关系,并且可以创建或更新对象A.具体考虑A是客户而B是订阅(C和D是B中的虚拟对象属性)。

现在如果我尝试保存,我在C和D表中得到重复,而对象的管理似乎有效。 所以,我认为在进行关系之前我应该​​分离实体,但是当我调用SaveChanges()时我得到了这个错误:

存储更新,插入或删除语句会影响意外的行数(0)。自实体加载后,实体可能已被修改或删除。刷新ObjectStateManager条目。

以下是代码:


Customer customer = customerRepository.Get(ID);                  
if (customer == null)
{
     customer = new Customer();
     customer.Email = Request.Form["Email"].ToString();
}

Subscription subscription = new Subscription();
subscription.Active = true;
subscription.DateSubscription = DateTime.Today;

Object C = objectCRepository.Get(Request.Form["IDObjectC"]);//Get C object from database
Object D = objectDRepository.Get(Request.Form["IDObjectD"]);//Get D object from database

if (C != null)
{
    //I tried also to detach the objects before adding to subscription
    subscription.C = C;
    subscription.D = D;
    customer.Subscriptions.Add(subscription);

     if (customer.IDCustomer == 0)
         customerRepository.Add(customer);
     else
         UpdateModel(customer);

    customerRepository.Save();
}

这里是客户存储库的add和save方法:


public override void Add(Cliente cliente)
{
   db.Cliente.Add(cliente);
}

public override void Save()
{
  foreach (var entry in db.ChangeTracker.Entries()
               .Where(e => e.State == EntityState.Modified || e.State == EntityState.Added            || e.State == EntityState.Unchanged || e.State == EntityState.Detached))
  {
     string state = ObjectContext.GetObjectType(entry.Entity.GetType()).Name + " " + entry.State.ToString();

  if (ObjectContext.GetObjectType(entry.Entity.GetType()).Name.Equals("C") ||  ObjectContext.GetObjectType(entry.Entity.GetType()).Name.Equals("D"))
  {
     entry.State = EntityState.Unchanged;
  }
  dbContext.SaveChanges();
}

我也尝试将它用于对象C和D.


((System.Data.Entity.Infrastructure.IObjectContextAdapter)dbContext).ObjectContext.Refresh(System.Data.Objects.RefreshMode.StoreWins, entry);

收到的错误是

要刷新的对象集合中索引0处的元素具有null EntityKey属性值,或者未附加到此ObjectStateManager。

我注意到在CTP5中添加了选项AsNoTracking(),我尝试使用它,但没有! 我还检查了操作中涉及的每个属性的并发模式,并且都设置为None。 我完成了想法:(!

任何帮助将不胜感激!谢谢!

1 个答案:

答案 0 :(得分:0)

实际上我在加载AsNoTracking()方法时解决了自己,在保存实体之前我将状态更改为Unchanged。

//On loading
Context.Object.AsNoTracking().SingleOrDefault(l => l.Property == Property);

//On saving
Object.State = EntityState.Unchanged;
Object.SaveChanges();

希望这有助于某人。