CA2227:集合属性应该是只读的

时间:2016-02-25 14:26:12

标签: c# code-analysis

我知道之前已经问过这个问题,但我找不到适合我情况的答案(哦,我真的希望我不会因为这个而被投票),所以,我们走了:

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

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;
                }
            }
        }

但是Code Analyzer现在抱怨我不应该在我的收藏中设置。如果我删除了setter,我不能(或者我不知道如何)在同一个数据库调用中填充该集合。如果我在两个单独的调用中断开此调用,一个用于获取Entity而另一个用于获取Entity.SecondEntities,我将不得不编写更多代码并对数据库进行更多调用,以及事实我必须在loop中为每个SecondEntity对象获取Entity并且我不认为在这种情况下这是最佳的(嗯,我实际上知道事实是一个坏主意,从循环查询数据库)。任何人都能纠正我吗?或者有没有其他方法来检索关系数据库,将它们投影到Dto类中,同时遵守我的集合readonly的规则?

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

提前谢谢你。如果这个代码看起来很乱或没有多大帮助,我可以用我项目中的真实代码替换它,如果这有帮助的话。

P.S ...我也从MSDN检查了这个例子,但我不知道这会如何适用于这种情况。

1 个答案:

答案 0 :(得分:1)

MSDN documentation 现在声明在这种情况下禁用警告是合理的。

<块引用>

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

还有其他替代方案需要考虑,具体取决于您的反序列化需求: