Проблема обратимого удаления Azure Mobile Services / рекомендации

При включенном мягком удалении я добавляю одну запись на клиенте, нажимаю, удаляю добавленную запись, а затем пытаюсь добавить новую запись (а затем нажимаю) с тем же первичным ключом, что и исходная запись. Я получаю исключение. Может показаться, что EntityDomainManager просто пытается сделать новую вставку, не проверяя, должна ли запись быть «обновлена», а не вставлена.

Однако, если я отключу мягкое удаление в конструкторе диспетчера домена, все будет работать нормально.

Мы используем инкрементную синхронизацию, поэтому мягкое удаление, как я понимаю, необходимо для того, чтобы эта работа работала, поэтому мы не получаем разных картинок того, что правильно между мобильным устройством и сервером.

Когда/являются рекомендуемым подходом? Пользовательский EntityDomainManager (или другой DomainManager)? Если да, то было бы полезно внести больше ясности во взаимодействие между контроллером таблицы и менеджером домена.

Я создал этот собственный менеджер доменов, который, похоже, работает, но буду признателен за любые рекомендации/предложения.

public class CustomEntityDomainManager<TData> : EntityDomainManager<TData> where TData : class, ITableData
{

    public CustomEntityDomainManager(DbContext context, HttpRequestMessage request, ApiServices services)
        : base(context, request, services)
    {
    }

    public CustomEntityDomainManager(DbContext context, HttpRequestMessage request, ApiServices services, bool enableSoftDelete) : base(context, request, services, enableSoftDelete)
    {
    }

    public async override Task<TData> InsertAsync(TData data)
    {
        if (data == null)
        {
            throw new ArgumentNullException("data");
        }

        // now then, if we have soft delete enabled & data has been provided with an id in it 
        if (EnableSoftDelete && data.Id != null)
        {
            // now look to see if the record exists and if it is deleted
    // if so we look to remove the record before then attempting the insert

            // record old value of deleted, since need to query to see if deleted.
            var oldIncludeDeleted = IncludeDeleted;

            try
            {
                IncludeDeleted = true;
                var existingData = await this.Lookup(data.Id).Queryable.FirstOrDefaultAsync();

                // if record exists, and its soft deleted then truly delete it
                if (existingData != null && existingData.Deleted)
                {
                    // now need to remove this record...
                    this.Context.Set<TData>().Remove(existingData);
                }
            }
            finally
            {
                IncludeDeleted = oldIncludeDeleted;        
            }
        }

        if (data.Id == null)
        {
            data.Id = Guid.NewGuid().ToString("N");
        }

        return await base.InsertAsync(data);
    }

person jamie    schedule 13.11.2014    source источник


Ответы (1)


Такое поведение предусмотрено дизайном — мы требуем, чтобы вы выполнили явную отмену удаления перед выполнением обновления.

Решение, которое вы представили, прекрасно. Вы также можете переместить код в контроллер таблицы, если вам нужно такое поведение только в одной таблице. Если вам нужно это в нескольких таблицах, то менеджер личного домена — лучший подход.

person lindydonna    schedule 17.11.2014