2016-11-14 5 views
2

私はAsp.Net Core + EF Core RESTサービスを持っています。 SPを呼び出すDBのDbContextクラスを作成しました。以下のような方法はかなりルックス:Asp.Net Core + EF Coreでデータをキャッシュするパターン?

public IQueryable<xxx> Getxxxs() 
{ 
    return Set<xxx>().FromSql("pr_Getxxx"); 
} 

このすべての作品が、SPにSPリターンはほとんど変化していないデータから一つ一つの時間を呼び出すの任意のポイントはありません。 24時間ごとにデータを失効させたいと思います。

コアでこれを行うためのパターンがありますか? .AddCaching拡張メソッドがあるのがわかりますが、コントローラに注入されるようですね。コントローラのジョブをキャッシュするのですか?スレッドセーフなので、ロックなど何もする必要はありません。競合状態のように見えます。あるスレッドがアイテムがキャッシュにロードされているかどうかをチェックしていて、他のスレッドがそのアイテムを挿入しているかどうかなどです。

+3

にDIの設定を変更することでキャッシュを無効にすることができるという利点があります。この名前は正式に6ヶ月間使用されていません。これはEntityFramework Coreと呼ばれ、EF6の次のバージョンではないことを明確にするためにバージョン1.0にバージョンアップされています。この発表をここで参照してくださいhttp://www.hanselman.com/blog/ASPNET5IsDeadIntroducingASPNETCore10AndNETCore10.aspx – Tseng

+0

このサービスは永久に実行されているのですか?何らかの理由で、データベースから最後にデータにアクセスしたときの結果とタイムスタンプをキャッシュする必要があります。 しかし、データベースは、このキャッシュ機能を単独で実行する必要があります。 –

+0

@ThomasRoskopでは、サービスは常に実行されています。 Coreが働く方法、コントローラとコンテキストは、それぞれの呼び出しで新しくなります。彼らはX時間後に失効することができるMemoryCacheを持っています。それは競争状態に開いているようです。 – SledgeHammer

答えて

1

よく、decorator patternを適用できます。 .NET Core固有のものではなく、共通のパターンです。

public class MyModel 
{ 
    public string SomeValue { get; set; } 
} 

public interface IMyRepository 
{ 
    IEnumerable<MyModel> GetModel(); 
} 

public class MyRepository : IMyRepository 
{ 
    public IEnumerable<MyModel> GetModel() 
    { 
     return Set<MyModel>().FromSql("pr_GetMyModel"); 
    } 
} 

public class CachedMyRepositoryDecorator : IMyRepository 
{ 
    private readonly IMyRepository repository; 
    private readonly IMemoryCache cache; 
    private const string MyModelCacheKey = "myModelCacheKey"; 
    private MemoryCacheEntryOptions cacheOptions; 

    // alternatively use IDistributedCache if you use redis and multiple services 
    public CachedMyRepositoryDecorator(IMyRepository repository, IMemoryCache cache) 
    { 
     this.repository = repository; 
     this.cache = cache; 

     // 1 day caching 
     cacheOptions = new MemoryCacheEntryOptions() 
      .SetAbsoluteExpiration(relative: TimeSpan.FromDays(1)); 
    } 

    public IEnumerable<MyModel> GetModel() 
    { 
     // Check cache 
     var value = cache.Get<IEnumerable<MyModel>>("myModelCacheKey"); 
     if(value==null) 
     { 
      // Not found, get from DB 
      value = Set<MyModel>().FromSql("pr_GetMyModel").ToArray(); 

      // write it to the cache 
      cache.Set("myModelCacheKey", value, cacheOptions); 
     } 

     return value; 
    } 
} 

ASP.NETコアDIはインターセプタやデコレータをサポートしていませんので、ごDI登録はもう少し冗長になります。または、デコレータ登録をサポートするサードパーティのIoCコンテナを使用します。

services.AddScoped<MyRepository>(); 
services.AddScoped<IMyRepository, CachedMyRepositoryDecorator>(
    provider => new CachedMyRepositoryDecorator(
     provider.GetService<MyRepository>(), 
     provider.GetService<IMemoryCache>() 
    )); 

これは、あなたが心配の明確な分離を持っていて、** ** EF7それを呼び出しを停止してくださいすることができ、容易

services.AddScoped<IMyRepository,MyRepository>();