【发布时间】:2016-07-09 21:36:52
【问题描述】:
我在实体框架 6(代码优先模型)中使用 DB 拦截来实现软删除功能,但是间歇性地我收到 SQL Server 抛出的异常,指出“您的 SQL 语句的某些部分是嵌套的太深了。重写查询或将其分解为更小的查询。"
这是一个正在生成的 sql 示例,您可以看到生成的 SQL 非常离谱:
https://gist.github.com/junderhill/87caceac728809a8ca837b9d8b5189f3
我的 EF Intercept 的代码如下:
public class SoftDeleteInterceptor : IDbCommandTreeInterceptor
{
public const string IsDeletedColumnName = "IsDeleted";
public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
{
if (interceptionContext.OriginalResult.DataSpace != DataSpace.SSpace)
{
return;
}
var queryCommand = interceptionContext.Result as DbQueryCommandTree;
if (queryCommand != null)
{
interceptionContext.Result = HandleQueryCommand(queryCommand);
}
}
private static DbCommandTree HandleQueryCommand(DbQueryCommandTree queryCommand)
{
var newQuery = queryCommand.Query.Accept(new SoftDeleteQueryVisitor());
return new DbQueryCommandTree(
queryCommand.MetadataWorkspace,
queryCommand.DataSpace,
newQuery);
}
public class SoftDeleteQueryVisitor : DefaultExpressionVisitor
{
public override DbExpression Visit(DbScanExpression expression)
{
var table = (EntityType)expression.Target.ElementType;
if (table.Properties.All(p => p.Name != IsDeletedColumnName))
{
return base.Visit(expression);
}
var binding = expression.Bind();
return binding.Filter(
binding.VariableType
.Variable(binding.VariableName)
.Property(IsDeletedColumnName)
.NotEqual(DbExpression.FromBoolean(true)));
}
}
【问题讨论】:
-
您应该查看 EF 团队项目经理的 this 工作。
-
不幸的是我仍然有同样的问题。我不明白为什么 EF 会为看起来应该很简单的东西生成如此晦涩的 SQL。
-
您找到解决方案了吗?
标签: sql-server entity-framework ef-code-first soft-delete