Entity Framework Core: InvalidOperationException

asp.net-core asp.net-identity entity-framework entity-framework-core


I'm trying to setup a method that returns all presentations that are not overlapping with presentations you have signed up for. However, when trying to implement this I came across an error I can't seem to fix, I looked around and haven't been able to find any similar issues. Am I missing something obvious?

This is the Error:

InvalidOperationException: variable 't0' of type 'Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor+TransparentIdentifier`2[NameSpace.Models.Presentation,Microsoft.EntityFrameworkCore.Storage.ValueBuffer]' referenced from scope '', but it is not defined

These are my models.

public class ApplicationUser : IdentityUser
    public List<Presentation> MyPresentations { get; set; }

    public List<PresentationUser> RegisteredPresentations { get; set; }

public class Presentation
    public int PresentationId { get; set; }

    public string HostId { get; set; }
    public ApplicationUser Host { get; set; }

    public List<PresentationUser> Attendees { get; set; }

    public int TimeId { get; set; }
    public PresentationTime Time { get; set; }

public class PresentationUser
    public int PresentationId { get; set; }
    public Presentation Presentation { get; set; }

    public string ApplicationUserId { get; set; }
    public ApplicationUser ApplicationUser { get; set; }

public class PresentationTime
    public int PresentationTimeId { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }

This is the method I can't get to work

private async Task<IQueryable<Presentation>> GetAvailablePresentations()
    User user = await context.Users
        .Include(u => u.RegisteredPresentations)
        .ThenInclude(eu => eu.Presentation.Host)
        .FirstOrDefaultAsync(u => u.Id == userManager.GetUserId(User));

    var Presentations = context.Presentations
        .Include(e => e.Host)
        .Include(e => e.Time)
        .Include(e => e.Attendees)
        .ThenInclude(e => e.ApplicationUser)
        // Filter Out Conditions
        .Where(e => e.Attendees.All(u => u.ApplicationUserId != user.Id))    // Cannot see Presentations they are attending.
        .Where(e => e.HostId != user.Id);                                    // Cannot see their own Presentation  

    var debug = user.RegisteredPresentations.Select(ex => ex.Presentation).ToList();

    // This section makes it so that users can't sign up for more that one Presentation per timeslot.
    // Error Occurs Here
    Presentations = Presentations.Where(e => debug.All(ex =>
        ex.Time.EndTime < e.Time.StartTime || e.Time.EndTime < ex.Time.StartTime));
    // This also does not work
    // Presentations = Presentations.Where(e => debug.All(ex => ex.Time.StartTime != e.Time.StartTime));

    return Presentations;

If anyone can help me fix this it would be huge help.

Note: I stripped a lot of other logic to help isolate this issue, so I may have a couple unnecessary .Include() in this code.

11/29/2016 7:46:42 PM

Accepted Answer

Presentations is not a list, it's still a IQueryable - a not-yet-executed query to DB. Applying Where you instruct EF to apply additional WHERE in SQL. But debug is a list of objects in memory (.ToList()). How you think EF will transfer them back to DB?

If you want all filtering be applied in DB - you should change debug to list of something "simple" (list of ids?) - then EF will be able to pass this list back to DB.

Alternatively, you should read all suitable Presentations into memory (call .ToList()) and apply last filtering in memory. You may calculate min(StartTime) and max(EndTime) from debug and apply this two simple values to Presentations query (you will receive less unnecessary items) then read to memory and apply "strong" filtering in memory.

11/29/2016 9:49:52 PM

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow