C# 学习实体框架6命令树拦截器
这纯粹是一个学习实验(耶,科学!)。这并不意味着要在任何地方实际使用。我想了解EF6的命令树拦截器是如何工作的 我正试图修改截获的命令树,以便在所有查询中添加一个“IsActive=1”过滤器。我注意到在这类事情的文档中有一个严重的缺陷。两个问题: 如何有选择地截取实现接口的实体的命令树(例如,C# 学习实体框架6命令树拦截器,c#,entity-framework,entity-framework-6,interceptor,C#,Entity Framework,Entity Framework 6,Interceptor,这纯粹是一个学习实验(耶,科学!)。这并不意味着要在任何地方实际使用。我想了解EF6的命令树拦截器是如何工作的 我正试图修改截获的命令树,以便在所有查询中添加一个“IsActive=1”过滤器。我注意到在这类事情的文档中有一个严重的缺陷。两个问题: 如何有选择地截取实现接口的实体的命令树(例如,IHasAnActiveProperty)?现在我注意到拦截器正在拦截历史上下文的查询,这与MyEntity无关 如何将筛选器添加到所有查询 public class MyEntity { [Da
IHasAnActiveProperty
)?现在我注意到拦截器正在拦截历史上下文的查询,这与MyEntity无关
如何将筛选器添加到所有查询
public class MyEntity
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
}
public class MyDbContext : DbContext
{
public DbSet<MyEntity> Entities { get; set; }
public MyDbContext() : base("default") { }
public MyDbContext(string nameOrConnectionString)
: base(nameOrConnectionString) {}
}
public class MyConfiguration : DbConfiguration
{
public MyConfiguration()
{
AddInterceptor(new MyInterceptor());
}
}
public class MyInterceptor : IDbCommandTreeInterceptor
{
public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
{
var query = interceptionContext.Result as DbQueryCommandTree;
if (query != null)
{
Debug.WriteLine("##################");
Debug.WriteLine("DataSpace: {0}", interceptionContext.Result.DataSpace);
Debug.WriteLine(query.ToString());
query.Query.Accept(new MyVisitor());
}
}
}
假设我们有这样的情况:
class Program
{
static void Main(string[] args)
{
using (var ctx = new MyDbContext())
{
var entities = ctx.Entities.FirstOrDefault(x => x.Name == "amy");
Console.WriteLine(entities);
}
}
}
此查询将生成此命令树:
DbQueryCommandTree
|_Parameters
|_Query : Collection{Record['Id'=Edm.Int32, 'Name'=Edm.String, 'IsActive'=Edm.Boolean]}
|_Project
|_Input : 'Limit1'
| |_Limit
| |_Filter
| | |_Input : 'Extent1'
| | | |_Scan : CodeFirstDatabase.MyEntity
| | |_Predicate
| | |_
| | |_'amy'
| | |_=
| | |_Var(Extent1).Name
| |_1
|_Projection
|_NewInstance : Record['Id'=Edm.Int32, 'Name'=Edm.String, 'IsActive'=Edm.Boolean]
|_Column : 'Id'
| |_Var(Limit1).Id
|_Column : 'Name'
| |_Var(Limit1).Name
|_Column : 'IsActive'
|_Var(Limit1).IsActive
但我不知道从这里该怎么办。我使用了以下参考资料来帮助我实现自定义的“软删除”拦截机制:
- (据我记忆所及,关于拦截器的部分大约在20分钟左右,重点是
节点,它应该回答您的问题)扫描
- (注释中有一个关于查询缓存问题的有趣观点)
希望这会有所帮助ExpressionVisitor的设计目的不是修改表达式,而是了解它的存在和/或记录它。如果你想修改命令,你必须从
IDbCommandInterceptor
@ErikPhilips中删除,这就解释了这么多。@Amy那么你有没有得到过代码的工作版本?我有兴趣从中学习。
DbQueryCommandTree
|_Parameters
|_Query : Collection{Record['Id'=Edm.Int32, 'Name'=Edm.String, 'IsActive'=Edm.Boolean]}
|_Project
|_Input : 'Limit1'
| |_Limit
| |_Filter
| | |_Input : 'Extent1'
| | | |_Scan : CodeFirstDatabase.MyEntity
| | |_Predicate
| | |_
| | |_'amy'
| | |_=
| | |_Var(Extent1).Name
| |_1
|_Projection
|_NewInstance : Record['Id'=Edm.Int32, 'Name'=Edm.String, 'IsActive'=Edm.Boolean]
|_Column : 'Id'
| |_Var(Limit1).Id
|_Column : 'Name'
| |_Var(Limit1).Name
|_Column : 'IsActive'
|_Var(Limit1).IsActive