序章
サーバーがEntityFramework5.0を使用してさまざまなデータベースにデータを格納するクライアントサーバーアーキテクチャがあります。したがって、異なるDbContext
クラスがあります。ただし、それらの間で共有されるいくつかのエンティティタイプがあります。だから私たちは持つことができます:
public class MyFirstDataAccess : DbContext
{
//constructor omitted
public DbSet<SharedType> MyEntities { get; set; }
public DbSet<OtherType> MyOtherEntities { get; set; }
}
public class MySecondDataAccess : DbContext
{
public DbSet<SharedType> MyEntitiesWithSharedType { get; set; }
}
もちろん、実際のエンティティは共有されません。
問題
プログラムのさまざまな部分で必要なのは、データの一部だけです。たとえば、一部はTypeのエンティティを使用できますSharedType
。そこで、データを提供する汎用インターフェースを作成しました。
public interface IEntityProvider<TEntity> where TEntity : class
{
DbSet<TEntity> Elements { get; set; }
void Dispose();
int SaveChanges();
}
にインターフェイスを実装するDbContext
と、プロパティが追加されます。たとえば、プロパティは次Elements
のように置き換えられます。MyEntitiesWithSharedType
DbSet<SharedType> IEntityProvider<SharedType>.Elements { get; set; }
これは実際に機能します。DbContext
プログラムのさまざまな部分が、必要なデータを提供する限り、どの部分でも機能するようになりました。
サーバーの一部をクライアントで再利用したい。もちろん、クライアントにはがありませんがDbContext
、サーバーからWCFサービスを介してデータを取得します。したがって、このインターフェイスはクライアントと共有する必要があるため、インターフェイスでDbSet
使用することはできません。そこで、必要なメンバーをIEntityProvider
含む別のインターフェイスを作成しました。DbSet's
public interface IEntityCache<TEntity> : IEnumerable<TEntity>, IQueryable<TEntity>
{
ObservableCollection<TEntity> Local { get; }
TEntity Add(TEntity entity);
TEntity Remove(TEntity entity);
}
問題は、をDbSet
として取得することIEntityCache
です。DbSet
すべてのメンバーが含まれていますが、インターフェイスを実装していないため、直接キャストすることはできません。私はいくつかの異なるアプローチを試しましたが、どちらも実際には機能しませんでした:
試行1
のサブクラスを作成しますDbSet
。これは、必要なインターフェイス(->クラスアダプタ)を実装します。
DbSet
パブリックまたは保護されたコンストラクターがないため、これは機能しません。したがって、アダプタクラスは無効です。
試行2
アダプタクラスを使用する代わりに、次のインターフェイスから派生したアダプタインターフェイスを使用しようとしましたIDbSet
。
public ICustomDbSet<SharedType> MyEntities{ get; set; }
IEntityCache<SharedType> IEntityProvider<SharedType>.Elements { get { return MyEntities; } }
EntityFrameworkはを設定しないため、これは機能しませんICustomDbSet
。おそらくそれが設定する値のために、はありませんIEntityCache
。
解決
この質問を書いている間、私はかなり良い解決策を見つけました(私は答えとして投稿します)。では、なぜこの質問を投稿するのですか?まず、もっと合理的と思われるアプローチが他にあるかどうか、そして私のソリューションにいくつかの欠点があるかどうかを知りたいと思います。第二に、解決策は他の誰かを助けるかもしれません。そして第三に、この質問を書くのに時間がかかり、それを捨てるのは残念です:)