EF Core 扩展方法
NCache 提供同步和异步扩展方法,用于在 EF Core 中缓存查询。 同步 API 是以下方法的扩展方法 IQueryable
接口,而异步 API 返回这些方法的任务实例。
备注
此功能也可用于 NCache Professional.
要使用以下 API,请在您的应用程序中包含以下命名空间:
Alachisoft.NCache.EntityFrameworkCore
NCache的 Entity Framework Core Caching Provider 包含以下用于缓存查询的 API:
同步 API | 异步 API |
---|---|
FromCache |
FromCacheAsync |
LoadIntoCache |
LoadIntoCacheAsync |
FromCacheOnly |
FromCacheOnlyAsync |
FromCache
扩展方法非常适合在处理事务性数据(具有频繁的读写操作)时使用。例如,维护飞行记录,其中每个独特的飞行都需要连续记录新条目的数据库。或者,对于参考数据(其中读取比写入更频繁),使用 LoadIntoCache
和 FromCacheOnly
扩展方法。就像在产品目录中一样,产品被视为参考数据,因为它们很少修改并且一致地从数据库中读取。要使用这些参考数据扩展方法,您需要在应用程序中定义查询索引。这可以通过添加动态完成 [QueryIndexable]
标签。
使用 EFCore 存储缓存数据
In FromCache
, LoadIntoCache
, FromCacheOnly
及其异步对应项,您可以使用 EF Core 缓存查询将数据存储在缓存中以供后续查询使用。
您可以通过两种方式将数据存储在缓存中:使用插入调用将整个数据集存储为数据存储中单个键的集合。或者,您可以针对多个键分别批量添加每个实体。您可以使用 CachingOption 进行此选择 StoreAs
设置 StoreAs.Collection
or StoreAs.SeperateEntities
。 您可以指定并启用 bulkInsertChunkSize
当处理大量实体时,例如 100,000 个。 这可以确保无论数据集的大小如何,数据都会逐块加载到缓存中,从而使数据存储过程更加高效且易于管理。
备注
bulkInsertChunkSize
属性将大量实体划分为较小的块,并逐块更新缓存。 因此,它允许操作通过在 90 秒限制内缓存实体块来解决连接超时问题,从而防止其触发取消令牌。 默认情况下, bulkInsertChunkSize
是1000。
重要
由于应用程序仅在缓存整个数据块后才收到响应,因此最好使用异步扩展方法以避免在处理大型数据集时出现任何明显的延迟。
来自缓存
FromCache
方法缓存根据 LINQ 查询生成的结果集数据并将其返回给应用程序。 如果缓存中不存在数据,则会从数据源中获取数据并存储到缓存中。 如果应用程序再次进行相同的查询,它将从缓存中获取必要的数据,从而避免不必要的数据源访问。
但是,由于此方法发生在两个级别(获取结果集数据和更新缓存),因此失败的可能性会增加,尤其是在后一种情况下。 您可能会因为多种原因而无法更新缓存。 例如,数据库连接失败、网络错误、缓存/服务器关闭、数据序列化失败、状态转移场景等。
因此, NCache 为用户提供雇佣 FromCache
与 errorEnabled
允许他们确定是否要因任何非结果集相关问题而停止应用程序的标志。一般来说,如果缓存和系统性能是优先考虑的,用户会将此标志设置为True(因为查询每次都会处理数据源,否则)。但是,如果他们的首要任务是阻止应用程序停止,则用户会将此标志设置为 False。
备注
默认情况下, errorEnabled
标志设置为 False。
备注
即使 errorEnabled
标志为 False,这些与更新缓存相关的异常将记录在以下位置的缓存日志中: %NCHome%/log-files
.
国际私人包机价格项目范例
- 以下示例根据指定的客户 ID 从数据库中获取客户详细信息,并将它们作为单独的实体存储在具有指定缓存选项的缓存中。
using (var context = new NorthwindContext())
{
var options = new CachingOptions
{
StoreAs = StoreAs.SeperateEntities
};
var resultSet = (from cust in context.Customers
where cust.CustomerId == someCustomerId
select cust).FromCache(options).ToList();
}
备注
您还可以使用以下命令监视缓存的活动 NCache 监控。
- 以下示例返回针对作为集合存储在缓存中的查询结果集数据内部生成的缓存键。 可以保存此密钥以供将来使用,例如从缓存中删除实体/结果集。
using (var context = new NorthwindContext())
{
var options = new CachingOptions
{
StoreAs = StoreAs.Collection
};
var resultSet = (from cust in context.Customers
where cust.CustomerId == someCustomerId
select cust).FromCache(out string cacheKey, options);
}
备注
通过使用 导出缓存键 在您选择的工具中,您可以查看特定缓存的缓存键。
FromCache 的注意事项
FromCache
支持以下功能:
Group By
Order By Ascending
Order By Descending
Sum
Min
Max
Average
Count
Contains
Like
FirstOrDefault
这些功能可以在使用 LINQ 时实现 FromCache
, 如下:
-
Like
EF Core 中的运算符在字符串内执行模式匹配。 通常,它与Where
inSELECT
根据列值中的特定模式或子字符串过滤行的语句。 此外,它允许使用通配符来匹配字符串中的一个或多个字符:
using (var context = new NorthwindContext())
{
var result = context.Customers
.Where(c => EF.Functions.Like(c.CompanyName, "Alfreds Futterkiste"))
.FromCache(options)
.ToList();
}
-
Contains
运算符可以类似于Like
运算符在给定条件内采用基于模式的搜索。
using (var context = new NorthwindContext())
{
var result = context.Customers
.Where(b => (b.CompanyName.Contains("Alfreds Futterkist")))
.FromCache(out cacheKey, options)
}
-
FirstOrDefault
运算符可以按如下所示实施。
using (var context = new NorthwindContext())
{
var result = context.Products
.Where(b => b.UnitPrice > 1)
.FromCache(out cacheKey, options)
.FirstOrDefault();
}
-
GroupBy
可以与 FromCache 的投影一起使用,如下所示。
using (var context = new NorthwindContext())
{
var resultSet = context.Products
.Where(p => p.UnitPrice == 10)
.GroupBy(p => p.ProductName)
.Select(group => group.Key)
.FromCache(out cacheKey, options)
.ToList();
}
加载到缓存
LoadIntoCache
API从源获取结果集数据并将其缓存,而不将其返回给应用程序。 该API允许后续 FromCache
调用以产生新数据。 这 LoadIntoCache
方法特别适合频繁更新的数据(例如客户订单)或敏感数据(例如付款详细信息)。在这种情况下,使用过时的数据可能会导致不正确的业务事务,因此,缓存中必须始终存在数据的新副本。此扩展方法将完整的工作数据集加载到缓存中。然后,该方法查询数据库,将结果存储在缓存中,并将其返回给应用程序。
国际私人包机价格项目范例
- 以下示例从数据库中获取客户订单并将结果集数据作为集合加载到缓存中。 它还返回内部生成的缓存密钥,可以保存该缓存密钥以供将来使用。
using (var context = new NorthwindContext())
{
var options = new CachingOptions
{
StoreAs = StoreAs.Collection
};
var resultSet = (from custOrder in context.Orders
where custOrder.Customer.CustomerId == someCustomerId
select custOrder).LoadIntoCache(out string cacheKey, options);
}
- 以下示例将特定订单详细信息作为指定缓存选项的单独实体从数据库加载到缓存中。
using (var context = new NorthwindContext())
{
var options = new CachingOptions
{
StoreAs = StoreAs.SeperateEntities
};
var resultSet = (from custOrder in context.Orders
where custOrder.Customer.CustomerId == someCustomerId
select custOrder).LoadIntoCache(options);
}
-
GroupBy
可与投影一起使用LoadIntoCache
如下实施。
using (var context = new NorthwindContext())
{
var resultSet = context.Products
.Where(p => p.UnitPrice == 10)
.GroupBy(p => p.ProductName)
.Select(group => group.Key)
.LoadIntoCache(out cacheKey, options)
.ToList();
}
每当您期望数据发生更改时,您都可以定期执行此方法。例如,如果您预计一周内数据会发生修改,那么在该时间段之后再次运行它可以确保缓存中的数据得到更新。
仅来自缓存
对于更新频率较低的数据(例如客户详细信息),定期从数据源获取数据的成本很高。 FromCacheOnly
查询缓存中存在的实体,并且在任何情况下都不会访问数据源。 本质上,如果实体不存在于缓存中,仍然不会从数据源中获取它。
备注
该API仅在实体单独存储时有效,即缓存选项 StoreAs
被设置为 SeperateEntities
.
重要
实体必须在索引中 NCache 使用前的管理中心 FromCacheOnly
.
- 以下示例从缓存中获取客户信息,如果 对客户的 实体存在。 如果不是,则返回的结果集将为空。
using (var context = new NorthwindContext())
{
var resultSet = (from cust in context.Customers
where cust.CustomerId == someCustomerId
select cust).FromCacheOnly();
}
FromCacheOnly 的注意事项
FromCacheOnly
支持聚合函数。 但是,这些函数仅缓存结果,而不缓存实体本身。 因此, NCache 提供 QueryDeferred
延迟查询的方法,以便缓存中的实体获得响应查询的结果。有关延迟 API 的更多详细信息,请参阅章节 查询延迟 API. FromCacheOnly
支持以下功能:
Group By
Order By Ascending
Order By Descending
Sum
Min
Max
Average
Count
Contains
Like
使用 LINQ 时请记住以下注意事项 FromCacheOnly
:
除了
Count
,所有聚合函数都必须具有整数值。Count
需要提供一个实体来计数。单个 LINQ 表达式
FromCacheOnly
不能使用多个聚合函数。LINQ 表达式中的投影只能在以下情况下执行:
GroupBy
运算符和聚合函数用于FromCacheOnly
.不支持多个投影。 LINQ 表达式中只能投影一个属性(即结转)。
using (var context = new NorthwindContext())
{
var result = context.Employees
.Select(e => e.EmployeeId) // Multiple projections have not been performed
.GroupBy(eid => eid) // eId was projected so GroupBy had to be used
.DeferredMin() // MIN provided with a numeric attribute
.FromCacheOnly();
}
GroupBy
主要用于聚合函数(使用列对查询结果进行分组),并且仅在预先完成投影并使用聚合函数时才能使用。GroupBy
必须是 LINQ 表达式中的最后一个运算符,除非 ifOrderBy
用来。 在这种情况下,GroupBy
功能可以向前移动(之后OrderBy
)或向后(之前OrderBy
).
using (var context = new NorthwindContext())
{
var result = context.Products
.Where(data => data.ProductName == "Tofu")
.GroupBy(data => new { data.ProductName})
.Select(group => new
{
_String = group.Key.ProductName,
Count = group.Count()
})
.FromCacheOnly();
}
OrderBy
(升序和降序)只能在 LINQ 表达式中使用FromCacheOnly
如果GroupBy
用来。超过一个
GroupBy
和OrderBy
运算符不能在单个 LINQ 表达式中使用FromCacheOnly
.不支持联接,因此
Include()
方法行不通。对于包含以下内容的 LINQ 表达式
DateTime
实例中,缓存集群中的所有节点必须具有相同的DateTime
格式设置。 否则会导致格式异常。 当DateTime.Now
和DateTime.Parse()
方法用于多节点缓存集群。 为了避免这种情况,请同步DateTime
在两台机器上格式化。 此外,使用DateTime.ParseExact()
超过DateTime.Parse()
,作为ParseExact()
API 限制用户指定格式DateTime
.Like
EF Core 中的运算符在字符串内执行模式匹配。 通常,它与Where
inSELECT
根据列值中的特定模式或子字符串过滤行的语句。 此外,它允许使用通配符来匹配字符串中的一个或多个字符:
using (var context = new NorthwindContext())
{
var result = context.Customers
.Where(c => EF.Functions.Like(c.CompanyName, "Alfreds Futterkiste"))
.FromCacheOnly()
.ToList();
}
-
Contains
运算符可以类似于Like
运算符在给定条件内采用基于模式的搜索。
using (var context = new NorthwindContext())
{
var result = context.Customers
.Where(b => (b.CompanyName.Contains("Alfreds Futterkist")))
.FromCacheOnly()
}
-
Contains
运算符也可用于在字典中进行搜索。
using (var context = new NorthwindContext())
{
var customerList = new List<string> { "CustomerId", "Alfreds Futterkiste" };
var result = context.Customers
.Where(b => customerList.Contains(b.CompanyName))
.FromCacheOnly();
}
异步 LINQ API
异步 API 与同步 API 具有相同的功能,但具有异步行为。 传递给这些方法的参数也是相同的。
重要
由于其异步性质, cacheKey
不会在任何异步调用中返回,例如 FromCacheAsync
和 LoadIntoCacheAsync
-作为 out
具有异步签名的方法不允许使用参数。
从缓存异步
如果缓存连接建立失败,则直接从数据库中获取数据。 但是,每发出 60 秒请求后,就会重试缓存连接。 后续请求将在上次请求 60 秒后尝试重新初始化缓存。 每当连接成功建立时,就会从缓存中获取数据。
以下示例根据指定的信息获取客户详细信息 客户ID 异步从数据库中获取数据,并将它们作为单独的实体存储在具有指定缓存选项的缓存中。
using (var context = new NorthwindContext())
{
var options = new CachingOptions
{
StoreAs = StoreAs.SeperateEntities
};
var task = (from cust in context.Customers
where cust.CustomerId == someCustomerId
select cust).FromCacheAsync(options);
task.Wait();
var resultSet = task.Result.ToList();
}
LoadIntoCache异步
以下示例将特定订单详细信息作为单独的实体从数据库加载到缓存中,并指定了缓存选项。
using (var context = new NorthwindContext())
{
var options = new CachingOptions
{
StoreAs = StoreAs.SeperateEntities
};
var task = (from custOrder in context.Orders
where custOrder.Customer.CustomerId == someCustomerId
select custOrder).LoadIntoCacheAsync(options);
task.Wait();
var resultSet = task.Result.ToList();
}
FromCacheOnly异步
以下示例仅从缓存中获取客户信息,如果 对客户的 实体存在。 如果不是,则返回的结果集将为空,因为数据库将被忽略。
using (var context = new NorthwindContext())
{
var options = new CachingOptions
{
StoreAs = StoreAs.SeperateEntities
};
var task = (from cust in context.Customers
where cust.CustomerId == someCustomerId
select cust).FromCacheOnlyAsync();
task.Wait();
var resultSet = task.Result.ToList();
}
参见
.NET: Alachisoft.NCache.EntityFrameworkCore 命名空间。
.NET: Alachisoft.NCache.运行时.缓存 命名空间。