EF Core操作Cosmos DB新增嵌套列表属性后手动投影映射报错咨询
解决方案
方案1:分阶段查询+内存映射(最稳妥,无翻译兼容性问题)
该方案绕开EF Core Cosmos 查询翻译器对嵌套集合投影的限制,先仅拉取存量已存在的字段,内存中补全新增属性默认值:
// 第一步:用匿名类型仅查询存量存在的字段,避免EF Core尝试映射不存在的NewProp var anonymousItems = await _context.Student .Where(x => !x.IsDeleted) .Select(x => new { x.Id, x.ProfId, Subjects = x.Subjects.Select(z => new { z.Id, z.Name }) }) .AsNoTracking() .ToListAsync(cancellationToken); // 第二步:内存中手动映射,给新增属性赋值默认值 var items = anonymousItems.Select(x => new Domain.Entities.Student { Id = x.Id, ProfId = x.ProfId, Subjects = x.Subjects.Select(z => new Domain.Entities.Subject { Id = z.Id, Name = z.Name, NewProp = 0 // 自定义默认值 }).ToList() }).ToList();
拿到映射完成的items集合后,直接批量更新回数据库即可完成存量数据默认值补全。
方案2:给POCO属性设置默认值(适合无需手动批量更新的场景)
直接在实体类的新增属性上声明默认值,EF Core读取到不存在的字段时会自动填充默认值,无需手动投影:
public class SubjectDTO { public string Id { get; set; } public string Name { get; set; } public int NewProp { get; set; } = 0; // 声明默认值 } // 同时建议给集合属性也设置默认值,避免空集合映射报错 public class Student { public string Id { get; set; } public string ProfId { get; set; } public List<SubjectDTO> Subjects { get; set; } = new(); }
报错原因说明
之前写法报错是因为直接在EF Core查询表达式中对嵌套集合做实体投影时,EF Core会尝试从Cosmos文档中读取目标实体的所有字段,包括存量文档不存在的NewProp,而NewProp是不可为空的值类型,读到空值就会抛出Nullable object must have a value异常。
内容的提问来源于stack exchange,提问作者samantha07
相关产品推荐
相关产品推荐

