实体框架CreateObjectset附加方法不更新

时间:2011-10-06 18:47:42

标签: c# entity-framework domain-driven-design repository-pattern unit-of-work

我使用示例关闭this link来更新SQL Server 2008中的数据库表,遵循存储库和工作单元模式。

虽然我有Insert工作。我很难获得更新和删除工作。更新不会出错,也不会更新。删除提供了与此The object cannot be deleted because it was not found in the ObjectStateManager.

类似的InvalidOperationException

对于插入和删除,我使用的是示例中给出的IObjectSet方法。对于更新,我使用我发送修改对象的IObjectSet.Attach(实体)方法。

下面的存储库代码和工作单元类:

存储库类

  

命名空间DataAccess {

public interface IGenericRepository<T>
    where T : class
{
    void AddRow(T entity);
    void UpdateRow(T entity);
    void Delete(T entity);
}


public abstract class GenericRepository<T> : IGenericRepository<T>
        where T : class
{


    protected IObjectSet<T> _objectSet;

    public GenericRepository(ObjectContext Context)
    {
        _objectSet = Context.CreateObjectSet<T>();

    }




        public void AddRow(T entity)
        {
            _objectSet.AddObject(entity);
        }

        public void UpdateRow(T entity)
        {
            _objectSet.Attach(entity);
        }

        public void Delete(T entity)
        {
            _objectSet.DeleteObject(entity);
        }

   }
} 

工作单位

namespace DataAccess 
{
    public interface IUnitOfWork
    {
        IGenericRepository<User> Users { get; }
        void Commit();
    }


    public class UnitOfWork : IUnitOfWork
    {

        private readonly ObjectContext _context;
        private UserRepository _userRepository;

        public UnitOfWork(ObjectContext Context)
        {

            if (Context == null)
            {
                throw new ArgumentNullException("Context wasn't supplied");
            }
            _context = Context;
        }



        public void Commit()
        {
            _context.SaveChanges();
        }

            public IGenericRepository<User> Users
            {
                get 
                {
                    if (_userRepository == null)
                    {
                        _userRepository = new UserRepository(_context);
                    }

                    return _userRepository;
                }
            }
    }
}

最后,我在调用代码中使用它进行更新

public void UpdateUser(UserData userData)
{
   using (mEntities context = new mEntities())
   {
     UnitOfWork uow = new UnitOfWork(context);
     User usr = new User(); //This is the Entity Framework class
     usr.ID = userData.RowID;
     usr.UserName = userData.Username;   //usr.UserName is the primary key in the table

     uow.Users.UpdateRow(usr);
     uow.Commit();
   }
}

但更新不会发生。我在这做错了什么?我正在使用带有EF 4的VS2010

感谢您的时间......

2 个答案:

答案 0 :(得分:1)

UpdateRow附加项目后,您需要将其标记为已修改。实体附加状态为Unchanged。但是,要修改状态,您需要访问ObjectStateManager,这是上下文的属性。在EF 4.1 I was told中,上下文中有一个方法Entry(),允许您设置状态。

要删除实体,必须在上下文中存在。如果尚未加载,则必须在删除之前将其附加。

还要注意使用new()CreateObject<T>()之间的difference

答案 1 :(得分:0)

因此,工作方式是更改Generic存储库类中的更新方法

public void UpdateRow(T entity)
{
    _objectSet.Attach(entity);
    _context.ObjectStateManager.ChangeObjectState(entity, System.Data.EntityState.Modified);
    _context.SaveChanges();
}

UnitOfWork类不再需要Commit()方法。所以现在我的调用代码就是这样..

public void UpdateUser(UserData userData)
{
   using (mEntities context = new mEntities())
   {
     UnitOfWork uow = new UnitOfWork(context);
     User usr = new User(); //This is the Entity Framework class
     usr.ID = userData.RowID;
     usr.UserName = userData.Username;   //usr.UserName is the primary key in the table

     uow.Users.UpdateRow(usr);
     //uow.Commit();
   }
}

希望这有助于其他任何人。虽然我已经彻底测试了这一点,但我认为这应该适用于大多数情况。

相关问题