Search code examples
c#entity-framework-6ef-core-2.0

Using Interfaces With DbSet, Possible with EF Core?


Back in EF 4 it was not possible. Is it possible to use interfaces with a DbSet in EF6 or EF Core?

public class LfSp3Ctx : DbContext, ILfSp3Ctx
{
    public DbSet<ILfSp3Project> ProjectSE { get; set; }
}

Solution

  • It is possible, but it requires some trickery. EF will only instantiate DbSet types directly. Thus, you'd have to create your own interface that wraps/exposes all the DbSet methods you want and the actual implementation takes the DbSet instance in its constructor. Then on the DbContext class, you have to do something like this:

    IDbSet<DigimonEntity> DigimonRepository => new DbSetRepository<DigimonEntity>(this.Digimons);
    
    DbSet<DigimonEntity> Digimons { get; set; }
    
    public class DbSetRepository<T> : IDbSet<T> where T : class
    {
        private readonly DbSet<T> _set;
        public DbSetRepository(DbSet<T> set) => _set = set;
    
        public Type ElementType => ((IQueryable<T>)_set).ElementType;
        public Expression Expression => ((IQueryable<T>)_set).Expression;
        public IQueryProvider Provider => ((IQueryable<T>)_set).Provider;
        public IEnumerator<T> GetEnumerator() => ((IEnumerable<T>)_set).GetEnumerator();
        IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<T>)_set).GetEnumerator();
    
        void IDataStoreRepositoryWrite<T>.Add(T entity) => _set.Add(entity);
        void IDataStoreRepositoryWrite<T>.Update(T entity) => _set.Update(entity);
        void IDataStoreRepositoryWrite<T>.Delete(T entity) => _set.Remove(entity);
    
        Task IDataStoreRepositoryWrite<T>.AddAsync(T entity, CancellationToken token) => _set.AddAsync(entity, token);
    }
    

    Something like this. Mine is kind of specific to the implementation I was trying to pull off at the time. :)