web-dev-qa-db-ja.com

DbContextがIDbContextインターフェイスを実装しないのはなぜですか?

Entity FrameworkにIDbContextインターフェイスがないのはなぜですか? SaveChanges()などのメソッドを備えた既存のインターフェースがあり、そこからカスタムデータベースコンテキストインターフェースを派生させることができれば、物事をテストするのは簡単ではないでしょうか?

public interface ICustomDbContext : IDbContext
{
    // add entity set properties to existing set of methods in IDbContext
    IDbSet<SomeEntity> SomeEntities { get; }
}
52
Grief Coder

私はこれを見るIDbContext

このリンクを参照 そして、そのインターフェイスでエンティティコンテキストの新しい部分クラスを作成します。

public partial class YourModelEntities : DbContext, IDbContext 

編集:この投稿を編集しました、This Works for me。私のコンテキスト

namespace dao
{
    public interface ContextI : IDisposable
    {
        DbSet<TEntity> Set<TEntity>() where TEntity : class;
        DbSet Set(Type entityType);
        int SaveChanges();
        IEnumerable<DbEntityValidationResult> GetValidationErrors();
        DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity:class;
        DbEntityEntry Entry(object entity);
        string ConnectionString { get; set; }
        bool AutoDetectChangedEnabled { get; set; }
        void ExecuteSqlCommand(string p, params object[] o);
        void ExecuteSqlCommand(string p);
    }
}

YourModelEntitiesは自動生成された部分クラスであり、同じ名前の新しい部分クラスを作成し、新しいコンテキストインターフェイスを追加する必要があります。この例ではContextIです

注:メソッドは自動生成コードに実装されているため、インターフェイスはすべてのメソッドを実装していません。

namespace dao
{
    public partial class YourModelEntities :DbContext, ContextI
    {
        public string ConnectionString
        {
            get
            {
                return this.Database.Connection.ConnectionString;
            }
            set
            {
                this.Database.Connection.ConnectionString = value;
            }
        }

        bool AutoDetectChangedEnabled
        {
            get
            {
                return true;
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public void ExecuteSqlCommand(string p,params object[] os)
        {
            this.Database.ExecuteSqlCommand(p, os);
        }

        public void ExecuteSqlCommand(string p)
        {
            this.Database.ExecuteSqlCommand(p);
        }

        bool ContextI.AutoDetectChangedEnabled
        {
            get
            {
                return this.Configuration.AutoDetectChangesEnabled;
            }
            set
            {
                this.Configuration.AutoDetectChangesEnabled = value;
            }
        }

    }
}
14
user1626116

私はそれについても考えていました。あなたがmockingDbContextに使用することを想定しています。理由はわかりませんが、モックされたクラスのために独自のDbSetを手動で実装する必要があることを除いて(とにかく独自のインターフェイスを書き換える必要があります)。

0

テストを複雑にするメソッドをオーバーライドして、実動DbContextを拡張する模擬DbContextを作成するだけです。これにより、プロダクションDbContextに対する変更はすべて、テストに自動的に反映され、オーバーライドされたメソッドは保存されます。永続性を処理し、DbContextを取得する他のクラスについては、それらを拡張するだけでなく、拡張されたモックDbContextを渡します。

namespace Test.Mocks
{  
    public sealed class MockDatabaseContext : MainProject.Persistence.Database.DatabaseContext
    {
        public MockDatabaseContext(ConfigurationWrapper config) : base(config)
        {

        }      
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {

            var dbPath = "test.db";
            optionsBuilder.UseSqlite($"Filename={dbPath}");


        }
    }
}

namespace Test.Mocks
{

    public class MockInventoryFacade : InventoryFacade
    {        
        public MockInventoryFacade(MockDatabaseContext databaseContext) : base(databaseContext)
        {

        }    
    }
}
0
Sean Anderson