实体框架 CreateObjectset Attach 方法未更新
我正在使用 这个链接,按照存储库和工作单元模式更新 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在
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 theObjectStateManager
which is a property of the context. In EF 4.1 I was told there's a methodEntry()
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()
andCreateObject<T>()
.因此,有效的方法是更改通用存储库类中的更新方法
UnitOfWork 类不再需要 Commit() 方法。所以现在我的调用代码就是这样做的..
希望这对其他人有帮助。尽管我还没有对此进行彻底测试,但我认为这应该适用于大多数情况。
So the way that worked was to change the update method in the Generic repository class
The UnitOfWork class doesn't need the Commit() method anymore. so now my calling code does just this..
Hope this helps anyone else. Although I havnt tested this thoroughly I think this should work for most situations.