0

Is it possile to create a DbQuery from model with lazy-loaded navigation properties? When I tried to do so, I got the following error

getting value from 'Prefix' on 'Castle.Proxies.ExtendedStudentProxy --> Unable to track an instance of type 'ExtendedStudent' because it is a query type, Only entity types may be tracked.

I thought that DbQuery are read only so aren't they supposed to not be tracked as a default behavior? Am I wrong?

This this a sample of the code I used:

models:

public class ExtendedStudent {
    public string FirsName {get; set;}
    public virtual Prefix Prefix {get; set;}
}

public class Prefix {
    public int Id {get; set;}
    public string Name {get; set;}
}

Startup.cs

   builder.AddDbContext<ApplicationDbContext>( b => b.UseLazyLoadingProxies()
       .UseSqlServer(connectionString));

ApplicationDbContext.cs

public class ApplicationDbContext {

    ...
    public DbSet<Proxy> Proxies {get; set;}
    public DbQuery<ExtendedStudent> ExtendedStudents {get; set;}
    ...
}
Ido
  • 168
  • 2
  • 15
  • As you see below, there's more to say about this. The first question that should have been asked is: could you show the code that throws the exception? Query types aren't tracked (and not supposed to be tracked) but it seems you query them in a way that's only appropriate to entity types. – Gert Arnold Aug 11 '19 at 12:43

1 Answers1

1

Yes, they're not tracked. That's the default (and only) behavior. I think the exception is a somewhat clumsy way to tell that. It would be weird for a non-tracked type to contain a tracked entity. Also, note that there's no mapping API for query types to define relationships, so it's clearly not supported.

The main reason why this can't be done is that query types can be queried from any type of SQL and it can't be guaranteed that the query behind the query type is composable. It's perfectly possible to populate query types from a stored procedure. Then there's no way for SQL, let alone EF, to join the result with a table to populate a navigation property.

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
  • The part *there's no mapping API for query types to define relationships* is not exactly correct. Since query types by definition are *keyless*, the only restriction is that they cannot be at the principal side of the relationship, as [explained in the docs](https://learn.microsoft.com/en-us/ef/core/modeling/query-types) - the paragraph starting with *Only support a subset of navigation mapping capabilities*. So in OP example the reference nav property (and FK) is supported. Just the referenced entity cannot have inverse collection nav property. – Ivan Stoev Aug 10 '19 at 12:51
  • And btw, queries on query types in most of the cases *are* composable, support `Include` etc. Just FYI :) – Ivan Stoev Aug 10 '19 at 12:54
  • 1
    OMG, looks like I should delve a bit deeper before I know what I'm talking about! – Gert Arnold Aug 11 '19 at 11:28
  • 1
    Lol, may be you shouldn't, at least now. Because looks like EF Core designers had no clear idea what they were doing - client eval, query types.In 3,0 the former will be removed and [Query types are consolidated with entity types](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes#query-types-are-consolidated-with-entity-types), basically introducing *keyless* entity type concept. – Ivan Stoev Aug 11 '19 at 12:12
  • 1
    Yeah, not the first time I'm getting wary of immersing myself in the depths of EF core. It wouldn't be the first time I try to get to the bottom of things only to see the bottom changed a coupla versions later. – Gert Arnold Aug 11 '19 at 12:38
  • Hi @Gert, Unrelated, but I'm so excited with their query translation rewrite progress - see what they do in the latest 3 preview: https://stackoverflow.com/a/57876672/5202563 – Ivan Stoev Sep 10 '19 at 18:58