1654967340
この記事では、NCacheを使用してEntityFrameworkCoreをキャッシングエンジンと統合する方法について説明します。この記事では、コンソールアプリケーションでEntity Framework Coreをセットアップする方法と、NCacheを使用して、ネイティブのメモリ内分散キャッシュを使用してデータベースに対してより高速なリクエストを行う方法の実際的な例を示します。
Entity Framework Coreは、Microsoftの最新のORMであるObject Relational Mapperであり、ソフトウェアアプリケーションがエンティティをさまざまなデータベースにマッピング、接続、および管理するのに役立ちます。Entity Framework Coreはオープンソースでクロスプラットフォームであり、Microsoftテクノロジを使用するソフトウェアで使用されるORMのトップ1です。
この記事を書いている時点で、Entity Framework Coreは、エンティティをデータベースに接続する2つの方法を提供しています。
NCacheは、オープンソースおよびクロスプラットフォームのソフトウェアでもあります。そのキャッシュサーバーは、.NET、Java、Scala、Python、およびNode.js用のスケーラブルなメモリ内分散キャッシュを提供します。この記事では.NETテクノロジーに焦点を当てているため、NCacheを使用して次の使用法を利用できます。
Entity Framework CoreとNCacheを使用するアプリケーションの間にキャッシュのレイヤーを追加できます。これにより、クエリの応答時間が改善され、NCacheのキャッシュされたエンティティからデータを取得する限り、データベースへのラウンドトリップの必要性が減ります。
NCacheを使用すると、各リクエストから送信されるオプションのセットを変えることができます。つまり、効率を上げるために、使用している結果セットに基づいてキャッシュを異なる方法で使用できます。
実際のサンプルで見るように、NCacheへの各リクエストでキャッシュオプションを提供する必要があり、それらのオプションは次のとおりです。
NCacheには、Entity Framework Coreの遅延呼び出しを処理するための独自の拡張メソッドがあり、それらは3つの異なるグループに属しています。
キャッシュされたオブジェクトを操作するNCacheのメソッド:
独自のオプションを使用して、単一のオブジェクトをキャッシュに挿入します。キャッシュキーを返します
var customerEntity = new Customers
{
CustomerId = "HANIH",
ContactName = "Hanih Moos",
ContactTitle = "Sales Representative ",
CompanyName = "Blauer See Delikatessen"
};
//Add customer entity to database
database.Customers.Add(customerEntity);
database.SaveChanges();
//Caching options for cache
var options = new CachingOptions
{
QueryIdentifier = "CustomerEntity",
Priority = Runtime.CacheItemPriority.Default,
};
//Add customer entity to cache
Cache cache = database.GetCache();
cache.Insert(customerEntity, out string cacheKey, options);
キャッシュから1つのオブジェクトを削除します。
var cust = new Customers
{
CustomerId = "HANIH",
ContactName = "Hanih Moos",
ContactTitle = "Sales Representative",
CompanyName = "Blauer See Delikatessen"
};
cache.Remove(cust);
キャッシュキーを渡してオブジェクトを削除します
cache.Remove("cacheKey");
クエリ識別子に一致するすべてのエンティティをキャッシュから削除します
Tag tag = new Tag(queryIdentifier);
cache.RemoveByQueryIdentifier(tag);
EntityFrameworkCore用のNCacheの拡張メソッド
キャッシュインスタンスを取得します。
using (var context = new NorthwindContext())
{
Cache cache = context.GetCache();
}
キャッシュされたデータがある場合は、データソースを経由せずに返されます。キャッシュされたデータがない場合、データはデータソースから返され、キャッシュされます。
var options = new CachingOptions
{
StoreAs = StoreAs.SeperateEntities
};
var resultSet = (from cust in context.Customers
where cust.CustomerId == 10
select cust).FromCache(options);
結果セットからcacheKeyを返す
var options = new CachingOptions
{
StoreAs = StoreAs.Collection
};
var resultSet = (from cust in context.Customers
where cust.CustomerId == 10
select cust).FromCache(out string cacheKey, options);
すべてのリクエストは最初にデータソースに送られ、その結果セットをキャッシュして返します。
var options = new CachingOptions
{
StoreAs = StoreAs.SeperateEntities
};
var resultSet = (from custOrder in context.Orders
where custOrder.Customer.CustomerId == 10
select custOrder)).LoadIntoCache(options);
結果セットからキャッシュキーを返す
var options = new CachingOptions
{
StoreAs = StoreAs.Collection
};
var resultSet = (from custOrder in context.Orders
where custOrder.Customer.CustomerId == 10
select custOrder)).LoadIntoCache(out string cacheKey, options);
データソースには絶対に行きません。リクエストはキャッシュにのみ送信されます。一致する結果がキャッシュされていない場合は、空の結果セットとして返されます。
インクルードと結合はFromCacheOnly()ではサポートされていません。
var resultSet = (from cust in context.Customers
where cust.CustomerId == someCustomerId
select cust).FromCacheOnly();
このサンプルでは、次のように非常に単純なモデル関係が作成されました。
[Serializable]
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public List<Transaction> Transactions { get; set; }
public Store Store { get; set; }
public int? StoreId { get; set; }
}
[Serializable]
public class Store
{
public int Id { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public ICollection<Product> AvailableProducts { get; set; }
public ICollection<Consumer> RegularConsumers { get; set; }
}
[Serializable]
public class Consumer
{
public int Id { get; set; }
public string Name { get; set; }
public Store FavouriteStore { get; set; }
public int? FavouriteStoreId { get; set; }
public List<Transaction> Transactions { get; set; }
}
[Serializable]
public class Transaction
{
public int Id { get; set; }
public Consumer Consumer { get; set; }
public int ConsumerId { get; set; }
public Product Product { get; set; }
public int ProductId { get; set; }
}
DBContextクラスには、NCache初期化設定とモデルの関係があります。
public class SampleDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// configure cache with SQLServer DependencyType and CacheInitParams
CacheConnectionOptions initParams = new CacheConnectionOptions();
initParams.RetryInterval = new TimeSpan(0, 0, 5);
initParams.ConnectionRetries = 2;
initParams.ConnectionTimeout = new TimeSpan(0, 0, 5);
initParams.AppName = "appName";
initParams.CommandRetries = 2;
initParams.CommandRetryInterval = new TimeSpan(0, 0, 5);
initParams.Mode = IsolationLevel.Default;
NCacheConfiguration.Configure("democache", DependencyType.SqlServer, initParams);
optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-AT3H2E;Initial Catalog=sampleDatabase;Integrated Security=True");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Store>()
.HasMany(x => x.AvailableProducts)
.WithOne(x => x.Store)
.HasForeignKey(x => x.StoreId)
.IsRequired(false)
.OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<Store>()
.HasMany(x => x.RegularConsumers)
.WithOne(x => x.FavouriteStore)
.HasForeignKey(x => x.FavouriteStoreId)
.IsRequired(false)
.OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<Transaction>()
.HasOne(x => x.Consumer)
.WithMany(x => x.Transactions)
.HasForeignKey(x => x.ConsumerId)
.IsRequired(false);
modelBuilder.Entity<Transaction>()
.HasOne(x => x.Product)
.WithMany(x => x.Transactions)
.HasForeignKey(x => x.ProductId)
.IsRequired(false);
}
public DbSet<Store> Stores { get; set; }
public DbSet<Consumer> Consumers { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<Transaction> Transactions { get; set; }
}
これは、キャッシュとの間でオブジェクトを操作するために必要なNCacheメソッドを持つクラスです。
public class NCacheExtensions
{
private SampleDbContext Database { get; set; }
private CachingOptions CachingOptions { get; set; }
private Cache Cache { get; set; }
public NCacheExtensions(SampleDbContext database)
{
this.Database = database;
this.CachingOptions = new CachingOptions
{
QueryIdentifier = "Sample QueryIdentifier",
Priority = Alachisoft.NCache.Runtime.CacheItemPriority.Default,
CreateDbDependency = false,
StoreAs = StoreAs.Collection
};
Cache = database.GetCache();
}
public string AddSingleEntity<T>(T entity)
{
Cache.Insert(entity, out string cacheKey, this.CachingOptions);
return cacheKey;
}
public void RemoveSingleEntity<T>(T entity)
{
Cache.Remove(entity);
}
public void RemoveSingleEntity(string cacheKey)
{
Cache.Remove(cacheKey);
}
public void RemoveByQueryIdentifier(string queryIdentifier)
{
var tag = new Tag(queryIdentifier);
Cache.RemoveByQueryIdentifier(tag);
}
public IEnumerable<Consumer> GetAllConsumersFromCache(CachingOptions cachingOptions)
{
return Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).FromCache(cachingOptions);
}
public async Task<IEnumerable<Consumer>> GetAllConsumersFromCacheAsync(CachingOptions cachingOptions)
{
return await Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).FromCacheAsync(cachingOptions);
}
public IEnumerable<Consumer> LoadAllConsumersIntoCache(CachingOptions cachingOptions)
{
return Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).LoadIntoCache(cachingOptions);
}
public async Task<IEnumerable<Consumer>> LoadAllConsumersIntoCacheAsync(CachingOptions cachingOptions)
{
return await Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).LoadIntoCacheAsync(cachingOptions);
}
public IEnumerable<Consumer> GetAllConsumersFromCacheOnly(CachingOptions cachingOptions)
{
return Database.Consumers.FromCacheOnly();
}
}
ここに、コンソールアプリケーションの開始点があります。NCacheに接続し、上記で提供された拡張メソッドを使用する方法の例を示します。
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
using (var context = new SampleDbContext())
{
var cachedContext = new NCacheExtensions(context);
Console.WriteLine("start LoadAllConsumersIntoCache " + DateTime.Now.ToString("HH:mm:ss.f"));
var loadInCache = cachedContext.LoadAllConsumersIntoCache(new CachingOptions { StoreAs = StoreAs.Collection, QueryIdentifier = "Sample QueryIdentifier" });
Console.WriteLine("finish LoadAllConsumersIntoCache" + DateTime.Now.ToString("HH:mm:ss.f"));
Console.WriteLine("start GetAllConsumersFromCache " + DateTime.Now.ToString("HH:mm:ss.f"));
var getFromCache = cachedContext.GetAllConsumersFromCache(new CachingOptions { Priority = Alachisoft.NCache.Runtime.CacheItemPriority.Default });
Console.WriteLine("finish GetAllConsumersFromCache " + DateTime.Now.ToString("HH:mm:ss.f"));
Console.WriteLine("start load from DBContext " + DateTime.Now.ToString("HH:mm:ss.f"));
var getFromDb = context.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product);
Console.WriteLine("finishg load from DBContext " + DateTime.Now.ToString("HH:mm:ss.f"));
var cachedEntity = cachedContext.AddSingleEntity<Consumer>(getFromDb.FirstOrDefault());
Console.WriteLine("cache key: " + cachedEntity);
cachedContext.RemoveSingleEntity(cachedEntity);
cachedContext.RemoveByQueryIdentifier("Sample QueryIdentifier");
}
}
}
アプリケーションの動作:
おめでとう!これで、EntityFrameworkCoreデータをキャッシュするためのNCacheの使用に成功しました。
このストーリーは、もともとhttps://www.c-sharpcorner.com/article/caching-in-entity-framework-core-using-ncache/で公開されました
1654967340
この記事では、NCacheを使用してEntityFrameworkCoreをキャッシングエンジンと統合する方法について説明します。この記事では、コンソールアプリケーションでEntity Framework Coreをセットアップする方法と、NCacheを使用して、ネイティブのメモリ内分散キャッシュを使用してデータベースに対してより高速なリクエストを行う方法の実際的な例を示します。
Entity Framework Coreは、Microsoftの最新のORMであるObject Relational Mapperであり、ソフトウェアアプリケーションがエンティティをさまざまなデータベースにマッピング、接続、および管理するのに役立ちます。Entity Framework Coreはオープンソースでクロスプラットフォームであり、Microsoftテクノロジを使用するソフトウェアで使用されるORMのトップ1です。
この記事を書いている時点で、Entity Framework Coreは、エンティティをデータベースに接続する2つの方法を提供しています。
NCacheは、オープンソースおよびクロスプラットフォームのソフトウェアでもあります。そのキャッシュサーバーは、.NET、Java、Scala、Python、およびNode.js用のスケーラブルなメモリ内分散キャッシュを提供します。この記事では.NETテクノロジーに焦点を当てているため、NCacheを使用して次の使用法を利用できます。
Entity Framework CoreとNCacheを使用するアプリケーションの間にキャッシュのレイヤーを追加できます。これにより、クエリの応答時間が改善され、NCacheのキャッシュされたエンティティからデータを取得する限り、データベースへのラウンドトリップの必要性が減ります。
NCacheを使用すると、各リクエストから送信されるオプションのセットを変えることができます。つまり、効率を上げるために、使用している結果セットに基づいてキャッシュを異なる方法で使用できます。
実際のサンプルで見るように、NCacheへの各リクエストでキャッシュオプションを提供する必要があり、それらのオプションは次のとおりです。
NCacheには、Entity Framework Coreの遅延呼び出しを処理するための独自の拡張メソッドがあり、それらは3つの異なるグループに属しています。
キャッシュされたオブジェクトを操作するNCacheのメソッド:
独自のオプションを使用して、単一のオブジェクトをキャッシュに挿入します。キャッシュキーを返します
var customerEntity = new Customers
{
CustomerId = "HANIH",
ContactName = "Hanih Moos",
ContactTitle = "Sales Representative ",
CompanyName = "Blauer See Delikatessen"
};
//Add customer entity to database
database.Customers.Add(customerEntity);
database.SaveChanges();
//Caching options for cache
var options = new CachingOptions
{
QueryIdentifier = "CustomerEntity",
Priority = Runtime.CacheItemPriority.Default,
};
//Add customer entity to cache
Cache cache = database.GetCache();
cache.Insert(customerEntity, out string cacheKey, options);
キャッシュから1つのオブジェクトを削除します。
var cust = new Customers
{
CustomerId = "HANIH",
ContactName = "Hanih Moos",
ContactTitle = "Sales Representative",
CompanyName = "Blauer See Delikatessen"
};
cache.Remove(cust);
キャッシュキーを渡してオブジェクトを削除します
cache.Remove("cacheKey");
クエリ識別子に一致するすべてのエンティティをキャッシュから削除します
Tag tag = new Tag(queryIdentifier);
cache.RemoveByQueryIdentifier(tag);
EntityFrameworkCore用のNCacheの拡張メソッド
キャッシュインスタンスを取得します。
using (var context = new NorthwindContext())
{
Cache cache = context.GetCache();
}
キャッシュされたデータがある場合は、データソースを経由せずに返されます。キャッシュされたデータがない場合、データはデータソースから返され、キャッシュされます。
var options = new CachingOptions
{
StoreAs = StoreAs.SeperateEntities
};
var resultSet = (from cust in context.Customers
where cust.CustomerId == 10
select cust).FromCache(options);
結果セットからcacheKeyを返す
var options = new CachingOptions
{
StoreAs = StoreAs.Collection
};
var resultSet = (from cust in context.Customers
where cust.CustomerId == 10
select cust).FromCache(out string cacheKey, options);
すべてのリクエストは最初にデータソースに送られ、その結果セットをキャッシュして返します。
var options = new CachingOptions
{
StoreAs = StoreAs.SeperateEntities
};
var resultSet = (from custOrder in context.Orders
where custOrder.Customer.CustomerId == 10
select custOrder)).LoadIntoCache(options);
結果セットからキャッシュキーを返す
var options = new CachingOptions
{
StoreAs = StoreAs.Collection
};
var resultSet = (from custOrder in context.Orders
where custOrder.Customer.CustomerId == 10
select custOrder)).LoadIntoCache(out string cacheKey, options);
データソースには絶対に行きません。リクエストはキャッシュにのみ送信されます。一致する結果がキャッシュされていない場合は、空の結果セットとして返されます。
インクルードと結合はFromCacheOnly()ではサポートされていません。
var resultSet = (from cust in context.Customers
where cust.CustomerId == someCustomerId
select cust).FromCacheOnly();
このサンプルでは、次のように非常に単純なモデル関係が作成されました。
[Serializable]
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public List<Transaction> Transactions { get; set; }
public Store Store { get; set; }
public int? StoreId { get; set; }
}
[Serializable]
public class Store
{
public int Id { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public ICollection<Product> AvailableProducts { get; set; }
public ICollection<Consumer> RegularConsumers { get; set; }
}
[Serializable]
public class Consumer
{
public int Id { get; set; }
public string Name { get; set; }
public Store FavouriteStore { get; set; }
public int? FavouriteStoreId { get; set; }
public List<Transaction> Transactions { get; set; }
}
[Serializable]
public class Transaction
{
public int Id { get; set; }
public Consumer Consumer { get; set; }
public int ConsumerId { get; set; }
public Product Product { get; set; }
public int ProductId { get; set; }
}
DBContextクラスには、NCache初期化設定とモデルの関係があります。
public class SampleDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// configure cache with SQLServer DependencyType and CacheInitParams
CacheConnectionOptions initParams = new CacheConnectionOptions();
initParams.RetryInterval = new TimeSpan(0, 0, 5);
initParams.ConnectionRetries = 2;
initParams.ConnectionTimeout = new TimeSpan(0, 0, 5);
initParams.AppName = "appName";
initParams.CommandRetries = 2;
initParams.CommandRetryInterval = new TimeSpan(0, 0, 5);
initParams.Mode = IsolationLevel.Default;
NCacheConfiguration.Configure("democache", DependencyType.SqlServer, initParams);
optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-AT3H2E;Initial Catalog=sampleDatabase;Integrated Security=True");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Store>()
.HasMany(x => x.AvailableProducts)
.WithOne(x => x.Store)
.HasForeignKey(x => x.StoreId)
.IsRequired(false)
.OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<Store>()
.HasMany(x => x.RegularConsumers)
.WithOne(x => x.FavouriteStore)
.HasForeignKey(x => x.FavouriteStoreId)
.IsRequired(false)
.OnDelete(DeleteBehavior.NoAction);
modelBuilder.Entity<Transaction>()
.HasOne(x => x.Consumer)
.WithMany(x => x.Transactions)
.HasForeignKey(x => x.ConsumerId)
.IsRequired(false);
modelBuilder.Entity<Transaction>()
.HasOne(x => x.Product)
.WithMany(x => x.Transactions)
.HasForeignKey(x => x.ProductId)
.IsRequired(false);
}
public DbSet<Store> Stores { get; set; }
public DbSet<Consumer> Consumers { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<Transaction> Transactions { get; set; }
}
これは、キャッシュとの間でオブジェクトを操作するために必要なNCacheメソッドを持つクラスです。
public class NCacheExtensions
{
private SampleDbContext Database { get; set; }
private CachingOptions CachingOptions { get; set; }
private Cache Cache { get; set; }
public NCacheExtensions(SampleDbContext database)
{
this.Database = database;
this.CachingOptions = new CachingOptions
{
QueryIdentifier = "Sample QueryIdentifier",
Priority = Alachisoft.NCache.Runtime.CacheItemPriority.Default,
CreateDbDependency = false,
StoreAs = StoreAs.Collection
};
Cache = database.GetCache();
}
public string AddSingleEntity<T>(T entity)
{
Cache.Insert(entity, out string cacheKey, this.CachingOptions);
return cacheKey;
}
public void RemoveSingleEntity<T>(T entity)
{
Cache.Remove(entity);
}
public void RemoveSingleEntity(string cacheKey)
{
Cache.Remove(cacheKey);
}
public void RemoveByQueryIdentifier(string queryIdentifier)
{
var tag = new Tag(queryIdentifier);
Cache.RemoveByQueryIdentifier(tag);
}
public IEnumerable<Consumer> GetAllConsumersFromCache(CachingOptions cachingOptions)
{
return Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).FromCache(cachingOptions);
}
public async Task<IEnumerable<Consumer>> GetAllConsumersFromCacheAsync(CachingOptions cachingOptions)
{
return await Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).FromCacheAsync(cachingOptions);
}
public IEnumerable<Consumer> LoadAllConsumersIntoCache(CachingOptions cachingOptions)
{
return Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).LoadIntoCache(cachingOptions);
}
public async Task<IEnumerable<Consumer>> LoadAllConsumersIntoCacheAsync(CachingOptions cachingOptions)
{
return await Database.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product).LoadIntoCacheAsync(cachingOptions);
}
public IEnumerable<Consumer> GetAllConsumersFromCacheOnly(CachingOptions cachingOptions)
{
return Database.Consumers.FromCacheOnly();
}
}
ここに、コンソールアプリケーションの開始点があります。NCacheに接続し、上記で提供された拡張メソッドを使用する方法の例を示します。
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
using (var context = new SampleDbContext())
{
var cachedContext = new NCacheExtensions(context);
Console.WriteLine("start LoadAllConsumersIntoCache " + DateTime.Now.ToString("HH:mm:ss.f"));
var loadInCache = cachedContext.LoadAllConsumersIntoCache(new CachingOptions { StoreAs = StoreAs.Collection, QueryIdentifier = "Sample QueryIdentifier" });
Console.WriteLine("finish LoadAllConsumersIntoCache" + DateTime.Now.ToString("HH:mm:ss.f"));
Console.WriteLine("start GetAllConsumersFromCache " + DateTime.Now.ToString("HH:mm:ss.f"));
var getFromCache = cachedContext.GetAllConsumersFromCache(new CachingOptions { Priority = Alachisoft.NCache.Runtime.CacheItemPriority.Default });
Console.WriteLine("finish GetAllConsumersFromCache " + DateTime.Now.ToString("HH:mm:ss.f"));
Console.WriteLine("start load from DBContext " + DateTime.Now.ToString("HH:mm:ss.f"));
var getFromDb = context.Consumers.Include(x => x.Transactions).ThenInclude(x => x.Product);
Console.WriteLine("finishg load from DBContext " + DateTime.Now.ToString("HH:mm:ss.f"));
var cachedEntity = cachedContext.AddSingleEntity<Consumer>(getFromDb.FirstOrDefault());
Console.WriteLine("cache key: " + cachedEntity);
cachedContext.RemoveSingleEntity(cachedEntity);
cachedContext.RemoveByQueryIdentifier("Sample QueryIdentifier");
}
}
}
アプリケーションの動作:
おめでとう!これで、EntityFrameworkCoreデータをキャッシュするためのNCacheの使用に成功しました。
このストーリーは、もともとhttps://www.c-sharpcorner.com/article/caching-in-entity-framework-core-using-ncache/で公開されました