CA2227:集合属性应为只读

本文关键字:只读 属性 集合 CA2227 | 更新日期: 2023-09-27 18:36:08

考虑我的实体模型中有以下类:

public Entity{
   public int ID {get; set;}
   ....
   public virtual ICollection<SecondEntity> SecondEntities { get; set; }
}

和 DTO:

public EntityDto{
   public int ID {get; set;}
   ....
   public virtual ICollection<SecondEntityDto> SecondEntities { get; set; }
}

现在,在我的数据访问层中,我正在使用投影,因此GetAll()方法如下所示:

public async Task<ICollection<EntityDto>> GetAll()
        {
            using (var context = new entityContext())
            {
                try
                {
                    return await Task.FromResult(
                     context.Entity.Select(p => new EntityDto() {
                            Id = p.Id,
                            SecondEntities = p.SecondEntities.Select(q => new SecondEntity() {
                                 Id = q.Id })
                            .ToList() })
                     .ToList());
                }
                catch (System.Exception ex)
                {
                    log.Error("Error", ex);
                    throw;
                }
            }
        }

但是代码分析器现在抱怨我不应该在我的收藏中设置设置器。如果我删除 setter,我无法(或者我不知道如何)在对数据库的同一调用中填充该集合。如果我在 2 个单独的调用中中断此调用,一个用于获取Entity,第二个用于获取Entity.SecondEntities,我将不得不编写更多代码并对数据库进行更多调用,再加上我必须在loop中执行此操作才能获得每个Entity对象的SecondEntity,我认为在这种情况下这不是最佳的(好吧, 我实际上知道这是一个坏主意,从循环查询数据库)。谁能纠正我?或者有没有其他方法可以检索关系数据库,将它们投影到 Dto 类中,同时遵守readonly我的集合的规则?

显然,它也在抱怨签名(嵌套泛型类型),但从我所读到的内容来看,对于 1-2 级嵌套,我应该忽略它。

附言...我也从 MSDN 检查了这个例子,但我看不出它如何适用于这种情况。

CA2227:集合属性应为只读

MSDN 文档现在指出,在这种情况下禁用警告是合理的。

如果属性是数据传输对象 (DTO) 类的一部分,则可以禁止显示警告。否则,不要禁止显示此规则中的警告。

还有其他

替代方法需要考虑,具体取决于您的反序列化需求:

  • 在 DTO 中包含接受对象并从中设置其属性的构造函数
  • 根据更新 CA2227 使用初始化资源库 (C# 9) 不报告仅初始化属性