如何从Entity Framework中的IDbCommandInterceptor返回空结果?

时间:2017-12-18 14:06:30

标签: c# entity-framework entity-framework-6

我试图在Entity Framework 6中实现IDbCommandEnterceptor。拦截器的工作是让我访问执行的查询,而不实际执行它。

拦截器正在工作,但是当我用interceptionContext.SuppressExecution()阻止查询执行时,导致查询执行的代码在实体框架NullReferenceException方法中抛出ToList 。我假设这是因为ToList正在尝试读取未设置的查询结果的内容,因为执行被阻止了。

  

System.NullReferenceException:未将对象引用设置为实例   一个对象。       在System.Data.Entity.Core.Common.Internal.Materialization.Shaper' 1.Finally()   在     System.Data.Entity.Core.Common.Internal.Materialization.Shaper' 1.SimpleEnumerator.Dispose()   在System.Data.Entity.Internal.LazyEnumerator' 1.Dispose()at   System.Collections.Generic.List`1..ctor(IEnumerable' 1 collection)
  在System.Linq.Enumerable.ToList [TSource](IEnumerable' 1来源)at at   AgentOctal.EntityFramework.Hinter.Tests.DbContextTests.DbContext_ShouldAllowInteception()   在   C:\ Users \用户uffnerb \源\回购\ AgentOctal.EntityFramework.Hinter \ AgentOctal.EntityFramework.Hinter.Tests \ DbContextTests.cs:线   22

我目前的拦截代码如下:

internal partial class MyInterceptor : IDbCommandInterceptor
{
    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        Debug.WriteLine($"Intercepting query ({MethodBase.GetCurrentMethod().Name}): {command.CommandText}");
        interceptionContext.SuppressExecution();
        NotifyMonitor(interceptionContext.DbContexts, command.CommandText);
    }

    ...
    //5 other identical methods on IDbCommandInterceptor
    ...

}

执行被拦截查询的代码示例如下:

var query = context.Contacts.Where(c => c.FirstName == "Bradley");
var results = query.ToList();  //Exception is thrown inside this call to ToList

在阻止执行后,如果代码尝试运行查询而不知道查询被截获并被阻止,我该怎么做才能返回空结果?

1 个答案:

答案 0 :(得分:1)

您需要将Result设置为某些内容(这也会抑制执行)。例如:

public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) {
    Console.WriteLine($"Intercepting query ({MethodBase.GetCurrentMethod().Name}): {command?.CommandText ?? "{{no command text}}"}");            
    // dummy empty reader
    interceptionContext.Result = new DataTableReader(new DataTable());
    NotifyMonitor(interceptionContext.DbContexts, command.CommandText);
}