实体框架 CreateObjectset Attach 方法未更新

发布于 2024-12-08 10:46:51 字数 2819 浏览 3 评论 0原文

我正在使用 这个链接,按照存储库和工作单元模式更新 SQL Server 2008 中的数据库表。

虽然我已经让插入工作了。我很难让更新和删除工作正常进行。更新没有报错,也不更新。删除会给出如下所示的 InvalidOperationException The object Cannot be前景可删除,因为在 ObjectStateManager 中找不到它。

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

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

存储库类

命名空间数据访问{

公共接口 IGenericRepository;
    其中 T :类
{
    void AddRow(T 实体);
    void UpdateRow(T 实体);
    无效删除(T实体);
}


公共抽象类 GenericRepository; : IGenericRepository
        其中 T :类
{


    受保护的IObjectSet _objectSet;

    公共 GenericRepository(ObjectContext 上下文)
    {
        _objectSet = Context.CreateObjectSet();

    }




        公共无效AddRow(T实体)
        {
            _objectSet.AddObject(实体);
        }

        公共无效UpdateRow(T实体)
        {
            _objectSet.Attach(实体);
        }

        公共无效删除(T实体)
        {
            _objectSet.DeleteObject(实体);
        }

   }
} 

工作单元类

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();
   }
}

但更新没有发生。我在这里做错了什么?我正在使用 VS2010 和 EF 4

感谢您的宝贵时间...

I am using an example off this link to update database tables in SQL Server 2008 following the repository and Unit of Work pattern.

While I have got the Insert working. I am having a hard time getting the update and delete working. The update gives no error, and does not update. The delete gives an InvalidOperationException like this The object cannot be deleted because it was not found in the ObjectStateManager.

For insert and delete I am using the IObjectSet methods as given in the example. For Update I am using the IObjectSet.Attach(entity) method to which I send the modified object.

Code for Repository and Unit of work classes below:

Repository Class

namespace 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);
        }

   }
} 

Unit Of Work Class

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;
                }
            }
    }
}

Finally this is how I use it for update in my calling code

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();
   }
}

But the update doesn't happen. What am I doing wrong here? I am using VS2010 with EF 4

Thanks for your time...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

她说她爱他 2024-12-15 10:46:51

UpdateRow 中附加项目后,您需要将其标记为已修改。实体以“Unchanged”状态附加。但是,要修改状态,您需要访问 ObjectStateManager,它是上下文的一个属性。在 EF 4.1 中 我被告知上下文中有一个方法Entry(),允许您设置状态也是如此。

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

另请注意 使用 new()CreateObject()

After you attached an item in UpdateRow you need to mark it as modified. Entities are attached in the state Unchanged. However to modify the state you'll need access to the ObjectStateManager which is a property of the context. In EF 4.1 I was told there's a method Entry() in the context that allows you to set the state as well.

To delete an entity it has to be present in the context. If it hasn't been loaded you'll have to attach it before deleting it.

Also be aware about the difference between using new() and CreateObject<T>().

蓝色星空 2024-12-15 10:46:51

因此,有效的方法是更改​​通用存储库类中的更新方法

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();
   }
}

希望这对其他人有帮助。尽管我还没有对此进行彻底测试,但我认为这应该适用于大多数情况。

So the way that worked was to change the update method in the Generic repository class

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

The UnitOfWork class doesn't need the Commit() method anymore. so now my calling code does just this..

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();
   }
}

Hope this helps anyone else. Although I havnt tested this thoroughly I think this should work for most situations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文