Entity Framework - Удалить объект в Oracle 10g {Операция недопустима из-за текущего состояния объекта} - PullRequest
4 голосов
/ 07 ноября 2011

Я пытаюсь использовать шаблон репозитория в Entity Framework на Oracle 10g. Я упростил свой код:

Вот код SQL:

-- Create table
create table TESTTABLE
(
  MODULE_UNIQUE_ID VARCHAR2(32) not null,
  PANEL_STATUS     VARCHAR2(8) not null
)
tablespace SYSTEM
  pctfree 10
  pctused 40
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );
-- Create/Recreate primary, unique and foreign key constraints 
alter table TESTTABLE
  add constraint TESTTABLE_PK_01 unique (MODULE_UNIQUE_ID)
  using index 
  tablespace SYSTEM
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );

Я создаю простой класс репозитория:

public interface IRepository<TEntity, TCtx>
{
    TCtx Session { get;}
    void Add(TEntity entity);
    void AddOrAttach(TEntity entity);
    void Delete(TEntity entity);
    int Save();
    TEntity SelectByKey(string colName, string key);
}

public class Repository<TEntity, TCtx> : IRepository<TEntity, TCtx>,
    IDisposable
    where TEntity : EntityObject
    where TCtx : ObjectContext
{
    #region Private fields

    private TCtx _ctx;
    private string _keyProperty = "ID";

    public int Save()
    {
        return _ctx.SaveChanges();
    }

   public TEntity SelectByKey(string colName, string key)
    {
        KeyProperty = colName;

        // First we define the parameter that we are going to use the clause.
        var xParam = Expression.Parameter(typeof(TEntity), typeof(TEntity).Name);
        MemberExpression leftExpr = Expression.Property(xParam, KeyProperty);
        Expression rightExpr = Expression.Constant(key);
        BinaryExpression binaryExpr = Expression.Equal(leftExpr, rightExpr);

        //Create Lambda Expression for the selection
        Expression<Func<TEntity, bool>> lambdaExpr = Expression.Lambda<Func<TEntity, bool>>
            (binaryExpr, new ParameterExpression[] { xParam });

        //Searching ....
        //IList<TEntity> resultCollection = ((IRepository<TEntity, TCtx>)this).SelectAll(new Specification<TEntity>(lambdaExpr));

        //if (null != resultCollection && resultCollection.Count() > 0)
        //{
        //    //return valid single result
        //    return resultCollection.First();
        //}
        //return null;

        return ((IRepository<TEntity, TCtx>) this)
            .SelectAll(new Specification<TEntity>(lambdaExpr)).FirstOrDefault();
    }

    public void Delete(TEntity entity)
    {
        _ctx.DeleteObject(entity);

    }

 }

Проблема в том, что сначала я выбираю какую-то сущность, а затем хочу удалить. Селект работает против БД Oracle хорошо. Проблема в обновлении или удалении команды.

   var _repo = new Repository<TESTTABLE, Entities>(
            new Entities(ConfigurationManager.ConnectionStrings["Entities"]
                          .ConnectionString));

    var obj = _repo.SelectByKey("MODULE_UNIQUE_ID", "11111");
    _repo.Delete(obj);
    _repo.Save();

Я получаю это исключение:

{"Произошла ошибка при обновлении записей. См. Внутренний исключение для деталей. "}

Внутреннее исключение:

{"Операция недействительна из-за текущего состояния объекта."}

StackTrace:

в System.Data.Mapping.Update.Internal.UpdateTranslator.CreateCommand (DbModificationCommandTree commandTree) в System.Data.Mapping.Update.Internal.DynamicUpdateCommand.CreateCommand (UpdateTranslator переводчик, словарь 2 identifierValues) at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary 2 identifierValues, List`1 Генерируемые значения) в System.Data.Mapping.Update.Internal.UpdateTranslator.Update (IEntityStateManager stateManager, адаптер IEntityAdapter)

Я снова протестировал свой класс репозитория. База данных MS SQL работает хорошо.

Что может вызвать эту проблему?

Ответы [ 2 ]

1 голос
/ 12 октября 2012

Я помню, что видел что-то вроде этого:

_context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
  1. Загрузка / Присоединение объекта
  2. Пометить как измененное / отслеженное
  3. Удалить / Удалить из контекста
  4. Сохранить

    MSDN Notes http://msdn.microsoft.com/en-us/library/system.data.objects.objectstatemanager.aspx

связанный пост Отслеживание изменений ObjectContext в Entity Framwwork

По соображениям производительности вы можете загрузить объект без отслеживания изменений

0 голосов
/ 12 сентября 2012

Похоже, вы извлекаете объект без использования ObjectContext.

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

Когда вы затем пытаетесь удалить его через контексттекущее состояние объекта "отсоединено", что недопустимо для операции удаления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...