Как создать DbModificationClause с помощью CASE WHEN .... THEN

Все

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

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

Код для тестирования. Класс Interseptor для поддельного удаления.

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].[Устройства] SET [DeletedDate] = [DeletedDate] IS NULL@0[DeletedDate] WHERE ([Id] = @1) @0: '01.05.2018 7:45:22' (Type = DateTime2) @1: '20' (Type = Int32)

0 ответов

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