实体框架计数异步抛出异常

时间:2016-03-04 18:29:25

标签: c# entity-framework linq asynchronous

我们进行了同步调用以获得符合某些标准的处置计数。工作查询看起来像这样。

            itemsCount = _db.Disposals
                .Include(d => d.ItemIds)
                .AsEnumerable()
                .Where(d => d.OrganizationId == SelectedOrganizationID &&
                            d.CreateDateTime.UtcDateTime > greaterThen.ToUniversalTime() &&
                            d.CreateDateTime.UtcDateTime < lessThen.ToUniversalTime())
                .SelectMany(d => d.ItemIds)
                .Count();

我需要使查询异步。似乎我需要一个IQueryable来运行CountAsync。我不明白为什么上面的代码首先有.AsEnumerable(),以及下面代码抛出异常的原因:

  

类型&#39; System.NotSupportedException&#39;的第一次机会异常。发生在mscorlib.dll

            itemsCount = await _db.Disposals
                .Include(d => d.ItemIds)
                .Where(d => d.OrganizationId == SelectedOrganizationID &&
                            d.CreateDateTime.UtcDateTime > greaterThen.ToUniversalTime() &&
                            d.CreateDateTime.UtcDateTime < lessThen.ToUniversalTime())
                .SelectMany(d => d.ItemIds)
                .CountAsync();

我真的只是在寻找为什么异步计数不起作用(项目确实构建,但随后抛出异常)。但是,理解为什么使用AsEnumerable()将是一个额外的好处。

P.S。我知道当我等待它前面时,它并没有异步运行,只是在那里进行测试。 _db是EF数据库上下文。

编辑:编写为:

时仍会抛出异常
            var greaterThanUtc = greaterThen.ToUniversalTime();
            var lessThanUtc = greaterThen.ToUniversalTime();

            itemsCount = await _db.Disposals
                .Include(d => d.ItemIds)
                .Where(d => d.OrganizationId == SelectedOrganizationID &&
                            d.CreateDateTime.UtcDateTime > greaterThanUtc &&
                            d.CreateDateTime.UtcDateTime < lessThanUtc)
                .SelectMany(d => d.ItemIds)
                .CountAsync();
  

类型&#39; System.NotSupportedException&#39;的第一次机会异常。   发生在mscorlib.dll

编辑2:

我认为问题是尝试将SQL中的Date字段(datetimeoffset)转换为d.CreateDateTime.UtcDateTime,我猜EF根本不支持这一点。

1 个答案:

答案 0 :(得分:4)

函数调用ToUniversalTime()无法转换为商店表达式,因此无法在数据库端运行。

.AsEnumerable()会导致它之后的所有内容在客户端上运行,因此您可以使用该.NET方法。

请注意,运行更多客户端通常不是必要的。对ToUniversalTime()的调用发生在似乎是局部变量的地方。你可以这样像

var greaterThanUtc = greaterThen.ToUniversalTime()

然后在查询中使用greaterThanUtc,而不使用.ToUniversalTime();

lessThen相同。

<强>更新

如果您的数据库字段是datetimeoffset,则必须在C#中使用DateTimeOffset。见Entity Framework Mapping DateTimeOffset to SQL Server DateTime