realmvpisme
realmvpisme

Reputation: 55

Automatically Infer DbContext Type

I've created a base service which runs CRUD commands on a database using EF Core that I want other services to inherit. I'm trying to figure out if there is a way to infer the type being queried by the DbContext based on the types being passed to the service.

public class DbServiceBase<TDatabaseModel, TBusinessDisplayModel>
{
    private readonly DbContext _context;
    private readonly Mapper _mapper;

    public DbServiceBase(DbContext context)
    {
        _context = context;
        _mapper = new Mapper(MapperConfigurationGenerator.Invoke());
    }

    public async Task<List<TBusinessDisplayModel>> GetAll()
    {
        var dbResults = await _context.<TDatabaseModel>
            .ToListAsync()
            .ConfigureAwait(false);

        return _mapper.Map<List<TBusinessDisplayModel>>(dbResults);
    }

    public async Task<TBusinessDisplayModel> GetById(long id)
    {
        var dbResult = await _context.<TDbModel>
            .SingleAsync(x => x.Id == id)
            .ConfigureAwait(false);

        return _mapper.Map<TBusinessDisplayModel>(dbResult);
    }
}

Upvotes: 1

Views: 157

Answers (2)

fbede
fbede

Reputation: 901

DbContext has a method called Set, that you can use to get a non-generic DbSet, such as:

dbSet = this.Set<SomeType>();

You should save this dbset in a private readonly field of you service and use this to query data.

Upvotes: 1

poke
poke

Reputation: 387607

The properties on the database context that are used to access the models in the database are usually implemented like this:

public DbSet<Post> Posts { get; set; }

EF will automatically populate those properties for your with database set objects for those entity types but you can also just create a database set from the context directly by calling DbContext.Set<T>. Since that method is already generic, you can use it to create the database set for the type you need in your implementation:

public async Task<List<TBusinessDisplayModel>> GetAll()
{
    var dbResults = await _context.Set<TDatabaseModel>()
        .ToListAsync()
        .ConfigureAwait(false);

    return _mapper.Map<List<TBusinessDisplayModel>>(dbResults);
}

Upvotes: 0

Related Questions