Как создать DbModificationClause с CASE WHEN .... THEN

все

Я создал IDbCommandTreeInterceptor и получил проблему: поставщик EF неправильное создание sql. В результате я хочу получить этот SQL

UPDATE [dbo].[Devices] SET [DeletedDate] = CASE 
WHEN [DeletedDate] IS NULL THEN GETUTCDATE()    
ELSE [DeletedDate] END 

Код для тестирования. Класс-перехватчик для фальшивого удаления.

public class SoftDeleteInterseptor : IDbCommandTreeInterceptor
{
    private const string DELETED_DATE_COLUMN = "DeletedDate";        

    public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
    {
        if (interceptionContext.OriginalResult.DataSpace != DataSpace.SSpace)
        {
            return;
        }            

        var deleteCommand = interceptionContext.OriginalResult as DbDeleteCommandTree;
        if (deleteCommand != null)
        {
            interceptionContext.Result = HandleDeleteCommand(deleteCommand);
            return;
        }
    }

    private DbCommandTree HandleDeleteCommand(DbDeleteCommandTree deleteCommand)
    {
        if (!IsPropertyExists(deleteCommand, DELETED_DATE_COLUMN))
        {
            return deleteCommand;
        }

        var deletedProperty = DbExpressionBuilder.Property(
            DbExpressionBuilder.Variable(deleteCommand.Target.VariableType, deleteCommand.Target.VariableName),
            DELETED_DATE_COLUMN
        );

        var caseValue = DbExpressionBuilder.Case(
            new DbExpression[] { deletedProperty.IsNull() },
            new DbExpression[] { EdmFunctions.CurrentUtcDateTime() },
            deletedProperty);

        var setClauses = new List<DbModificationClause> { DbExpressionBuilder.SetClause(deletedProperty, caseValue) };

        return new DbUpdateCommandTree(
            deleteCommand.MetadataWorkspace,
            deleteCommand.DataSpace,
            deleteCommand.Target,
            deleteCommand.Predicate,
            setClauses.AsReadOnly(), null);            
    }

    private bool IsPropertyExists(DbModificationCommandTree command, string property)
    {
        var table = (EntityType)command.Target.VariableType.EdmType;
        return table.Properties.Any(p => p.Name == property);
    }

}

Создайте класс конфигурации для регистра DbInterseptor.

public class CustomDbConfiguration : DbConfiguration
{
    public CustomDbConfiguration()
    {
        AddInterceptor(new SoftDeleteInterseptor());
    }
}
public partial class CustomDbContext : DbContext
{
    static IDCompleteDbContext()
    {
        DbConfiguration.SetConfiguration(new CustomDbConfiguration());
    }

    public virtual DbSet<CommandEntity> CommandEntities { get; set; }
}

public class CommandEntity
{
    public int Id {get; set;}
    public DateTime? DeletedDate {get; set;}
    public string Name {get; set;}
}

При удалении сущности сущность не удалялась

var context = new CustomDbContext();
var entity = context.CommandEntities.First();
context.CommandEntities.Remove(entity);
context.SubmitChanges();

Не сработало. Поставщик EF генерирует неправильный SQL: UPDATE [dbo]. [Devices] SET [DeletedDate] = [DeletedDate] IS NULL @ 0 [DeletedDate] WHERE ([Id] = @ 1) @ 0: '01 .05.2018 7:45:22 '(Тип = DateTime2) @ 1:' 20 '(Тип = Int32)

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

Ivan Stoev 01.05.2018 16:29

Я добавил еще код

VintVV80 02.05.2018 09:43

Спасибо, мне удалось это воспроизвести. Хорошо то, что ваш код в порядке. Плохо то, что после просмотра исходного кода EF генератор SQL для Sql Server некорректно обрабатывает выражения CASE в командах DML (вставка, обновление, удаление). Скорее всего, потому что сам EF не генерирует такие выражения. Я не вижу обходного пути, извините.

Ivan Stoev 02.05.2018 11:09
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
53
0

Другие вопросы по теме