【问题标题】:How do I return an empty result from an IDbCommandInterceptor in Entity Framework?如何从实体框架中的 IDbCommandInterceptor 返回空结果?
【发布时间】:2017-12-18 22:32:22
【问题描述】:

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

拦截器正在工作,但是当我使用interceptionContext.SuppressExecution() 阻止查询执行时,导致查询执行的代码在实体框架的ToList 方法中抛出了NullReferenceException。我假设这是因为 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() 在 System.Collections.Generic.List`1..ctor(IEnumerable'1 集合)
在 System.Linq.Enumerable.ToList[TSource](IEnumerable'1 源) 在 AgentOctal.EntityFramework.Hinter.Tests.DbContextTests.DbContext_ShouldAllowInteception() 在 C:\Users\uffnerb\source\repos\AgentOctal.EntityFramework.Hinter\AgentOctal.EntityFramework.Hinter.Tests\DbContextTests.cs:line 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

如何在阻止执行后返回空结果,因为尝试运行查询的代码不知道查询已被拦截和阻止?

【问题讨论】:

  • 也许添加一个 if 语句来检查 null 而不是简单地赋值?
  • 检查null 什么query 不是 null。异常是从实体框架深处抛出的(请参阅堆栈跟踪)。

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


【解决方案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);
}

【讨论】:

  • 为接口的ScalarExecuting 方法设置Result 的适当值是多少? null 好吗?
  • @BradleyUffner 不太确定,也许只是 SuppressExecution() 就像你做的那样一直都很好。我什至不确定 EF 上下文中的哪个正常操作使用这个 ExecuteScalar
  • 我会试一试。到目前为止,我的代码都没有达到那个方法,所以我会在以后处理它,如果它出现的话。感谢您的帮助。
猜你喜欢
  • 2015-05-29
  • 2015-08-24
  • 2020-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多