EF Core 5实体MatrixTypeId值与SQL查询结果不匹配问题
问题原因
- 核心原因1:EF Core 身份映射缓存机制
EF Core默认会为每个查询上下文启用身份映射(Identity Map):只要实体的主键值相同,就会复用同一个实体实例,不会用后续查询到的同主键记录的字段值覆盖已有实例。你的PriceListTest实体以Id作为唯一主键,查询结果中相同Id的多条记录仅第一个实例的属性会被赋值,后续同Id记录的MatrixTypeId不会更新,因此出现同Id的所有记录MatrixTypeId均与第一条一致的问题。 - 新增问题:
[NotMapped]特性阻断映射
你后续使用的CoCTestList实体中,MatrixTypeId被标记了[NotMapped]特性,EF Core会完全忽略该属性与数据库字段的映射关系,自然不会将查询结果中MATRIXTYPEID列的值赋值到该属性上。
修复方案
- 移除不必要的
[NotMapped]标记:删除CoCTestList.MatrixTypeId上的[NotMapped]特性,让EF Core可以正常映射该字段。 - 配置复合主键(推荐):根据你的业务数据的唯一规则,将
Id和MatrixTypeId配置为复合主键,避免同主键实例复用的问题。在OnModelCreating中添加如下配置:
// 针对PriceListTest的配置 modelBuilder.Entity<PriceListTest>().HasKey(p => new { p.Id, p.MatrixTypeId }); // 针对CoCTestList的配置 modelBuilder.Entity<CoCTestList>().HasKey(c => new { c.Id, c.MatrixTypeId });
- 添加无跟踪查询(临时验证/只读场景适用):如果你的查询仅用于读取数据不需要后续更新,可以在查询时添加
AsNoTracking(),直接关闭身份映射缓存,每条记录都会生成独立的实体实例,属性会按照查询结果赋值:
var productQuery = await context.PriceListTests .AsNoTracking() // 新增无跟踪配置 .Where(p => !existingTestIds.Contains(p.Id) && (p.Name.Contains(text) || p.Code.Contains(text)) && (p.ClientId == newClientId) && sampleMatrixTypes.Contains(p.MatrixTypeId)) .Distinct() .ToListAsync();
内容的提问来源于stack exchange,提问作者Samra
相关产品推荐
相关产品推荐

