Entity Framework Code First 和 CA2227 "集合属性应该只读"

12

在Entity Framework Code First中,一对多或多对多关系如下所示:

public class Foo
{
  public int Id { get; set; }
  public virtual ICollection<Bar> Bars { get; set; }
}

这违反了Code Analysis规则2227“集合属性应该是只读的”。

将setter方法设置为protected并不能解决问题,将其设置为private也不行:

public class Foo
{
  public int Id { get; set; }
  public virtual ICollection<Bar> Bars { get; private set; }
}

然后当然会违反CA1811规则,即"Foo.Bars.set(ICollection<Bar>)似乎没有任何上游公共或受保护的调用方"。

我不想全局关闭该规则,因为它存在的情况相当重要,但每次声明关系时都局部禁止它似乎不太合适。有没有一种方法可以声明关系而不违反CA2227?


我遇到了完全相同的问题。在没有找到任何合理的解决方案之后,我决定使用SuppressMessage()可能是最实用的方法。 - theDmi
2个回答

14

请将您的代码更改为以下内容:

public class Foo {
    public Foo() {
        Bars = new Collection<Bar>();
    }

    public int Id { get; set; }
    public virtual ICollection<Bar> Bars { get; private set; }
}

什么是好处? - HamsterWithPitchfork
可写的集合属性允许用户用完全不同的集合替换该集合。只读属性防止集合被替换,但仍允许设置单个成员。如果替换集合是目标,则首选设计模式是包括一种方法来删除集合中的所有元素,并重新填充集合的方法。https://learn.microsoft.com/en-us/visualstudio/code-quality/ca2227 - Professor of programming
我不同意,首选的设计模式仅适用于Java,在那里没有设置器和getter,您必须为每个属性自己编写它们。在C#中的Setters / Getters是专门为避免为每个属性编写冗余代码而创建的。特别是在与DB模型进行1:1映射的类中,完全没有理由将它们包装在方法中。 - HamsterWithPitchfork
你与微软的观点不一致,因为这是他们的观点和静态代码分析规则。 - Professor of programming

5
将所有代码实体放在自己的程序集中,并排除该程序集的规则。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接