如何创建DbModificationClause与CASE WHEN ....那么

时间:2018-05-01 11:53:42

标签: entity-framework-6

所有

我创建了IDbCommandTreeInterceptor并得到了问题:EF提供程序错误的sql生成。结果,我想得到这个SQL

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

测试代码。 Interseptor类假装delettion。

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:&#39; 01.05.2018 7: 45:22&#39; (Type = DateTime2)@ 1:&#39; 20&#39; (Type = Int32)

0 个答案:

没有答案