C# CA2227:集合属性应为只读
假设我的实体模型中有以下类:C# CA2227:集合属性应为只读,c#,code-analysis,C#,Code Analysis,假设我的实体模型中有以下类: public Entity{ public int ID {get; set;} .... public virtual ICollection<SecondEntity> SecondEntities { get; set; } } 但是代码分析器现在抱怨我的集合中不应该有setter。如果删除setter,则无法(或不知道如何)在对数据库的同一调用中填充该集合。如果我将此调用分为两个单独的调用,一个用于获取实体,第二个用于获取实体
public Entity{
public int ID {get; set;}
....
public virtual ICollection<SecondEntity> SecondEntities { get; set; }
}
但是代码分析器现在抱怨我的集合中不应该有setter。如果删除setter,则无法(或不知道如何)在对数据库的同一调用中填充该集合。如果我将此调用分为两个单独的调用,一个用于获取实体
,第二个用于获取实体。第二个实体
我将不得不编写更多代码并对数据库进行更多调用,加上我必须在循环中这样做才能为每个实体
对象获取第二个实体
,我认为在这种情况下这不是最优的(事实上,我知道从循环中查询数据库是个坏主意)。有人能纠正我吗?或者有没有其他方法可以检索关系数据库,将它们投影到Dto类中,同时遵守让我的集合成为只读的规则
显然,它也在抱怨签名(嵌套泛型类型),但从我读到的内容来看,对于1-2级嵌套,我应该忽略这一点
另外,我也从中检查了这个示例,但我不知道这将如何适用于这种情况。现在声明,在这种情况下禁用警告是合理的
如果属性是数据传输对象(DTO)类的一部分,则可以抑制该警告。
否则,请勿禁止显示此规则中的警告
根据您的反序列化需要,还有其他可供选择的方案:
- 在DTO中包含一个接受对象并从中设置其属性的构造函数
- 按照以下步骤使用初始设置器(C#9)
基本上,您不需要执行此操作,因为这将替换对集合的引用。您应该改为这样做:SecondEntities.Clear();SecondEntities.AddRange(…)
但是,我必须为该集合中的每个实体
编写一个循环,这意味着对于10000行数据,对该第二实体
的数据库进行10000次调用,这将极大地损害性能,而不仅仅是从调用中获取整个数据表。。另一个更好的方法是不投影,但与较大的表相比,它会再次损害性能。。。这显然没有什么害处。。(或与其他2个选项相比伤害更小)。。。我错了吗?你为什么需要一个循环?在您当前的代码中只有一个SecondEntities=因此,如果使用oleksii发布的代码提供SetSecondEntities(ICollection se)方法,您将得到相同的结果,您可以删除setter,顺便说一句,将字段设为只读。
public EntityDto{
public int ID {get; set;}
....
public virtual ICollection<SecondEntityDto> SecondEntities { get; set; }
}
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;
}
}
}