LINQ查询是否会绕过缓存直接访问数据库导致缓存失效?
相关代码
业务调用代码
var attribute = _genericAttributeService .GetAttributesForEntity(_workContext.CurrentCustomer.Id, "Customer") .FirstOrDefault(x => x.Key == "CompareProducts");
GetAttributesForEntity实现代码
public virtual IList<GenericAttribute> GetAttributesForEntity(int entityId, string keyGroup) { return _cacheManager.Get(string.Format(GENERICATTRIBUTE_KEY, entityId, keyGroup), () => { var query = from ga in _genericAttributeRepository.Table where ga.EntityId == entityId && ga.KeyGroup == keyGroup select ga; var attributes = query.ToList(); return attributes; }); }
结论
链式调用的FirstOrDefault是直接在缓存返回的内存列表中执行筛选,不会触发新的数据库查询
执行逻辑说明
- 当执行
GetAttributesForEntity方法时,首先会尝试从缓存中读取对应键的数据:- 若缓存命中:直接返回内存中已经存储好的
IList<GenericAttribute>集合 - 若缓存未命中:执行方法内部的查询逻辑,调用
ToList()时会立即触发数据库查询,拿到所有符合EntityId和KeyGroup条件的属性数据,存入缓存后再返回该集合
- 若缓存命中:直接返回内存中已经存储好的
- 后续链式调用的
FirstOrDefault属于LINQ to Objects方法,操作对象是已经加载到内存的IList集合,不会生成新的SQL语句,也不会发起新的数据库请求。
核心判定依据
LINQ操作分为两类:操作
IQueryable类型的LINQ to Entities会延迟执行,最终转换为SQL查询数据库;而操作IList等已加载内存集合的LINQ to Objects,全程在内存中执行,不会和数据库交互。本场景中GetAttributesForEntity返回类型是IList<GenericAttribute>,因此后续所有集合操作都在内存执行。
内容的提问来源于stack exchange,提问作者chris c
相关产品推荐
相关产品推荐

