Entity Framework CreateObjectset Attach метод не обновляется - PullRequest
2 голосов
/ 06 октября 2011

Я использую пример с по этой ссылке для обновления таблиц базы данных в SQL Server 2008 в соответствии с шаблоном хранилища и единицей работы.

Пока у меня работает вставка.Я испытываю трудности с получением обновления и удалением рабочих.Обновление не выдает ошибки и не обновляет.Удаление дает InvalidOperationException, как это The object cannot be deleted because it was not found in the ObjectStateManager.

Для вставки и удаления я использую методы IObjectSet, как указано в примере.Для обновления я использую метод IObjectSet.Attach (entity), в который отправляю измененный объект.

Код для классов репозитория и единиц работы ниже:

Класс репозитория

пространство имен 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();
   }
}

Но обновление не происходит.Что я здесь не так делаю?Я использую VS2010 с EF 4

Спасибо за ваше время ...

Ответы [ 2 ]

1 голос
/ 06 октября 2011

После того, как вы вложили элемент в UpdateRow, вам необходимо пометить его как измененный.Объекты прикреплены в состоянии Без изменений.Однако для изменения состояния вам понадобится доступ к ObjectStateManager, который является свойством контекста.В EF 4.1 мне сказали , что в контексте есть метод Entry(), который позволяет вам также установить состояние.

Чтобы удалить объект, он должен присутствовать в контексте.Если он не был загружен, вам придется прикрепить его перед удалением.

Также помните о разнице между использованием new() и CreateObject<T>().

0 голосов
/ 11 октября 2011

Таким образом, сработало изменение метода обновления в классе репозитория 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();
   }
}

Надеюсь, это поможет кому-то еще.Хотя я тщательно проверял это, я думаю, что это должно работать в большинстве ситуаций.

...