简体   繁体   中英

EntityFramework in .NetCore 3.1 and multiple DBContext

I have a.NetCore 2.2 app that is "working". My customer has asked for some modifications and I decided to try migrating the app to.NetCore 3.1. EntiryFramework is giving me fits.

My customer has a number of MS SQL "databases" like "Personnel", "Reservations", "Billing", etc. It is very common for me to have to create queries that match people from Personnel with billing and or other records from other DBs. I am doing this sort of thing in 2.2 now.

If I run a query similar to the following I get the exception:

Cannot use multiple DbContext instances within a single query execution. Ensure the query uses a single context instance.

This query appears to use a single context but there is that devicesInRoom entity buried in there. devicesInRoom is of type IQueryable<string> and comes from a "utility" query I ran earlier. Basically I want ONLY the reservations where the reservations.Device is the same as one of the items in devicesInRoom .

var reservations = (
    from reservation in reservationsContext.Reservations
    from reservationType in reservationsContext.Types.Where(
        reservationType => reservationType.Id.Equals(reservation.TypeId)
    ).DefaultIfEmpty()
    from roomMates in devicesInRoom
        .Where(
            roomMates => roomMates.Equals(reservation.Device)
        ).DefaultIfEmpty()
    where reservation.StartDate < viewEnd
          && reservation.EndDate > viewStart
          && reservation.Deleted.Equals(false)
    select reservation.Device
).ToList();

If I rewrite this query as:

var reservations = (
    from reservation in reservationsContext.Reservations
    from reservationType in reservationsContext.Types.Where(
        reservationType => reservationType.Id.Equals(reservation.TypeId)
    ).DefaultIfEmpty()
    where reservation.StartDate < viewEnd
          && reservation.EndDate > viewStart
          && reservation.Deleted.Equals(false)
    select reservation.Device
).ToList();

var thing = (
    from res in reservations
    from roomMates in devicesInRoom
        .Where(
            roomMates => roomMates.Equals(res)
        ).DefaultIfEmpty()
    select res
).ToList();

I still get the error above. I can't see why querying accross DBs is a bad thing.

How do I fix this?

I can't see why querying accross DBs is a bad thing.

EF has never supported it. EF Core 2x "solved" this and a number of other query translation limitations by simply evaluating the queries on the client. EF 3 dropped this "feature" and you have to explicitly declare when you want client-side evaluation by switching from LINQ-to-Entities to LINQ-to-Objects, typically by introducing .ToList() or .AsEnumerable() to transition from server-side evaluation to client-side evaluation.

Something like:

var reservations = (
    from reservation in reservationsContext.Reservations
    from reservationType in reservationsContext.Types.Where(
        reservationType => reservationType.Id.Equals(reservation.TypeId)
    ).DefaultIfEmpty().ToList()
    from roomMates in devicesInRoom.ToList()
        .Where(
            roomMates => roomMates.Equals(reservation.Device)
        ).DefaultIfEmpty()
    where reservation.StartDate < viewEnd
          && reservation.EndDate > viewStart
          && reservation.Deleted.Equals(false)
    select reservation.Device
).ToList();

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