NB I'm not asking how to find/filter entities in the DB. I'm not asking about the difference between Find
and Where
. I'm not asking about the implication of generics.
According to the docs, the DbContext
provides methods Find
and Find<T>
. Usually, I go through the DbSet
but noticing that there's Add()
on both the context directly and the DB set, I wanted to see what will happen if I try to filter directly on the context too, instead of the DB set.
I haven't found a single example of such call, though. A lot of information on going through the DB set and the differences mentioned in the disclaimer at the top. But I see no sample showing usage of Find()
nor Find<T>()
directly on the context.
Is it possible at all and if so, how? Intellisense is cryptic...
CodePudding user response:
When you use Find
on a DbSet, the Type of entity is known, so it just needs to Find by the provided ID.
When you use Find
on the DbContext, you either have to tell EF which Type
(Entity) to find against from its known mappings, or you can use the Generic version which defines the Type
of entity to search against.
Why would you use these methods instead of DbSet.Find
? One example would be where you don't want to expose an aspect of your domain as a DbSet
. For example if you have a DbSet of Customers, Businesses, etc. that all contain references to Address entities it would be uncommon to ever need to load an Address outside of that scope so you would probably opt not to expose a DbSet<Address>
in your domain to potentially be abused through convenience. In the case where your DbContext actually does need to locate a particular Address, you could use DbContext.Find<Address>(addressId)
to load it.
Honestly I don't use DbContext.Find()
, I don't even use DbSet.Find()
, I much, much prefer to work with IQueryable
and projection. But hey, it's an option. :)
CodePudding user response:
It does the same thing, but without using the DbSet
. It works by specifying the type
(entity) you want to fetch. You just have to specify the type, which must match your DbSet.
Is it possible at all and if so, how?
public class MyContext : DbContext
{
public MyContext(DbContextOptions<MyContext> options) : base(options) { }
public DbSet<City> Cities{ get; set; }
public DbSet<State> States { get; set; }
}
And use it like so:
MyContext context = CreateContext() // Or inject it...
// Will return the City which have id == 5.
object myUntypedCity = context.Find(typeof(City), 5);
// Will return the city which have id == [your guid].
City myTypedCity = context.Find<City>(Guid.NewGuid());
As a sidenote; Add()
on the Context works the same way. It will detect which type
of entity it is and put it on the correct DbSet
. I do not know what will happen if you have several DbSet
using the same type
.
why we have a non-generic Find() on the context given that quite a few DBs are using integers for IDs, hence ensuring ambiguous ID values between different entities/tables
In some scenarios you might not expose the DbSet
or you only know the type
of the entity. This can be very handy when making some very generic code where you don't have a typed entity nor know exactly what type of id (primary key) it has. It may be a Guid
or an int
. I myself have never found a practical use for Find
on the DbContext
.