简体   繁体   中英

Entity Framework Count Async Throws Exception

We had a synchrounous call to get a count of disposals that meet certain criteria. The working query looks like this.

            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();

I needed to make the query async. It seems that I need an IQueryable to run CountAsync on it. I don't understand why the code above had .AsEnumerable() in the first place, and why the code below throws an exception:

A first chance exception of type 'System.NotSupportedException' occurred in 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();

I am really just looking for why the async count doesn't work (the project does build, but then the exception is thrown). However, it would be a bonus to understand why AsEnumerable() is used.

PS I am aware that it's not running asynchrounously when I put await in front of it, that's just there for testing. _db is the EF database context.

edit: It still throws an exception when written as:

            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();

A first chance exception of type 'System.NotSupportedException' occurred in mscorlib.dll

EDIT 2:

I think the problem is trying convert a Date field in SQL (datetimeoffset) to d.CreateDateTime.UtcDateTime, I am guessing EF doesn't support this at all.

The function call ToUniversalTime() cannot be translated to a store expression, so it cannot run on the database side.

.AsEnumerable() causes everything that comes after it to run on the client, so you can use that .NET method.

Note it's generally a bad idea to run more client-side than necessary. The calls to ToUniversalTime() happen on what appear to be local variables. You could so something like

var greaterThanUtc = greaterThen.ToUniversalTime()

and then use greaterThanUtc in your query, with out .ToUniversalTime();

Same for lessThen .

UPDATE

If your database field is datetimeoffset you have to use DateTimeOffset in C#. See Entity Framework Mapping DateTimeOffset to SQL Server DateTime

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM