私はこの道を数回行ってきましたが、このように機能させたいという願望を理解していますが、私の経験では、実行可能ではないか、実行可能であれば努力する価値がありません. その理由は、多くの異なるストレージ エンジン (メモリ内キャッシュを含む) には、EF に簡単に適合できない違いがあるためです。たとえば、DbSet の些細なインメモリ キャッシュ実装では、トランザクション、レイジーまたはイーガー ロード スキームなどが受け入れられない場合があります。私の考えでは、Azure テーブル ストレージでスワップできるようにしたいと考えていました。ただし、その並べ替え、ページング、およびクエリは、SQL Server ほどリッチではありません。SQL では実行できるが、Azure Tables では実行できないクエリがいくつかあります。結局、私は常に、EF の背後にある永続化エンジンを交換する機能が魅力的に聞こえると信じています。
キャッシュをサポートする必要があり、ASP.NET Web API を実行していた場合は、その時点で API 要求/応答がキャッシュされるように、ASP.NET キャッシュを使用することを検討します。
さまざまなリレーショナル DB ベンダーのサポートが必要な場合は、サード パーティの EF プロバイダーを使用します。さまざまなデータベースの Entity Framework プロバイダーのリスト。
データ レイヤー内のキャッシュ、または大幅に異なる複数のストレージ エンジン (Mongo、Azure、SQL など) が必要な場合は、EF レイヤーの "上" で行います。このようなもの:
public interface ISomeDataProvider
{
SomeType Find(int id);
....
}
public class EfDataProvider : ISomeDataProvider
{
private SomeAppDbContext db = new SomeAppDbContext();
public SomeType Find(int id){
return db.SomeTypes.Find(id);
}
}
public class AzureTableDataProvider : ISomeDataProvider
{
public SomeType Find(int id){
return //Azure Table code
}
}
public class CachingDataProvider : ISomeDataProvider
{
private ISomeDataProvider source;
private static IList<SomeType> cache = new List<SomeType>(); //List used here, but could use .NET Cache, Redis, etc.
public CachingDataProvider(ISomeDataProvider source){
this.source = source;
}
public SomeType Find(int id){
var result = cache.SingleOrDefault(x=>x.Id == id)
if(result == null){
result = source.SingleOrDefault(x=>x.Id == id)
if(result != null) cache.Add(result); //Again, trivial cache example. Cache expiration, refresh, loading, etc. should be considered per-app
}
return result
}
}
とはいえ、私のアプリケーションの大部分では、考えてみると、永続化エンジンを交換する機能は実際には要件ではありません。私の顧客は、「SQL が必要な人もいれば、Azure テーブルが必要な人」もいません。これは私たちが行っている作業の種類によるものかもしれませんが、最終的には依存関係になり、EF に直接コーディングします。