向 POCO 添加方法或创建单独的类来更新 POCO 的值是一种好习惯吗?

Posted

技术标签:

【中文标题】向 POCO 添加方法或创建单独的类来更新 POCO 的值是一种好习惯吗?【英文标题】:Is it a good practice to add methods to the POCOs or to create separate class to update the values of the POCOs? 【发布时间】:2015-11-09 06:04:08 【问题描述】:

向 POCO 添加方法或创建单独的类来更新 POCO 的值以备不时之需是一种好习惯吗?

例如,

public class ForUser

    [Required]
    public int Depratment  get; set; 

    public List<SelectListItem> DepartmentsList  get; set; 

    [Required]
    public int Role  get; set; 

    [Required]
    [StringLength(200, MinimumLength = 3, ErrorMessage = "Length Of The First Name Should  Be More Than Three Letters")]
    public string FirstName  get; set; 

    [StringLength(200, MinimumLength = 3, ErrorMessage = "Length Of The Mid Name Should  Be More Than Three Letters")]
    public string MidName  get; set; 

    [Required]
    [StringLength(200, MinimumLength = 3, ErrorMessage = "Length Of The Last Name Should  Be More Than Three Letters")]
    public string LastName  get; set; 

    [Required]
    [EmailAddress(ErrorMessage = "Invalid Email Address")]
    public string Email  get; set; 

    [StringLength(14, MinimumLength = 10 , ErrorMessage = "Length Of The Mid Name Should  Be More Than Nine Letters and Less than fourteen Letters")]
    [RegularExpression(@"^[+]?[0-9]*", ErrorMessage="Phone Number is not correct")]
    public string PhoneNumber  get; set; 

    [Required]
    public string Password  get; set; 


    public int UserId  get; set; 
    public int Company  get; set; 
    public int Country  get; set; 
    public List<SelectListItem> Roles  get; set; 

我只是用它来保存数据以更新model entity 或将数据返回到视图。有时我需要在将object 发送到视图之前更新一些属性,例如上面示例中名为Roles 的列表,所以我想知道是否应该将这些方法添加到POCO 类中还是它最好创建一个类来更新属性?

【问题讨论】:

Adding methods to POCO classes 的可能重复项 请查看 ***.com/questions/4915957/… 的注释,并可能使用元类 re: 由 MS Silverlight 团队的 Austin Lamb 回答。虽然我在其他地方看到过一些关于元类的 cmets,但对我来说 POCO 对象似乎是合理的。 【参考方案1】:

Here你会找到你的问题的答案:

POCO 不是 DTO。 POCO 代表普通旧 CLR 对象,或普通 旧 C# 对象。它基本上是 POJO 的 .Net 版本,Plain Old Java 对象。 POCO 是您的业务对象。它有数据, 验证,以及您要放入的任何其他业务逻辑 那里。但是 POCO 没有一件事,那就是 使它成为 POCO。 POCO 没有持久性方法。如果你有 Person 类型的 POCO,不能有 Person.GetPersonById() 方法, 或 Person.Save() 方法。 POCO 仅包含数据和域逻辑, 没有任何类型的持久性逻辑。你会听到这个术语 概念是持久性无知(PI)。 POCO 是持久性 无知。

我更喜欢阅读整篇文章,不仅仅是为了得到你问题的答案,还要了解POCODTO之间的区别。

【讨论】:

【参考方案2】:

在这种情况下,POCO 具有 ViewModel 角色,因此,恕我直言,它应该只是一个数据传输对象 (DTO),并且只有最少量的代码。

可能是一些验证方法,可能是属性之间的一些基本计算,应该是这样。

【讨论】:

【参考方案3】:

这个问题是 DCI 用来解决的,通过将简单的 POCO/数据对象从功能中分离出来。

如果数据将在您描述的某种过程中更新,则在 DCI 中,您将基于用户心理模型将该过程建模为上下文,而不是基于服务、外观或任何其他工程师设计模式等抽象有效地将用户与系统断开连接,并将实际功能分散到整个系统中。

您的 POCO(系统 是什么)应该是精简的,功能(系统 做什么)应该包含您的 POCO 交互所需的内容。如果您努力使其保持简单,您将能够摆脱今天所谓的 OO 但实际上是面向类的无休止的抽象和限制,从而在软件设计中产生了如此多的问题。甚至多态性(现代 GOTO)也将不复存在,使系统行为成为一流。

【讨论】:

【参考方案4】:

你的类看起来更像是一个数据规范,因此应该保持原样。在这种情况下,将行为与模型分开。

【讨论】:

【参考方案5】:
//In my EnityModels folder is where I keep my POCO classes
//Nice and clean class
public class Model

    public int ModelID  get; set; 
    public string ModelName  get; set; 
    public int ModelSSN get; set; 
    public virtual ICollection<Language> Languages  get; set; 


/*Then in another folder called ModelVMs you would have your ViewModels
  ViewModels are usually not mapped to the Database
  I like to have a Constructor that does the data transfer for me

  This is also where I keep my methods as well as my property validation
  FYI: I also keep Flags and View Specific Properties in my ViewModel*/

public class ModelVM  //or ModelViewModel

    public ModelVM()  

    public ModelVM(Model model)
    
        this.ModelVMID = model.ModelID;    //yes the "this" in this example is unnecessary
        this.ModelVMName = model.ModelName;
        this.ModelVMSSN = model.ModelSSN;

        foreach(var lang in model.Languages)
        
            this.SLLanguages.Add(new SelectListItem() 
                                     
                                        Text = lang.LanguageName, 
                                        Value = lang.LanguageID
                                    
                                );
        
    

    [Required]
    public int ModelVMID get; set; 
    [Required]
    [Display(Name="Model Name")]
    public string ModelVMName get; set; 
    [Required]
    [Display(Name="We need your Social Security Number")]
    public int ModelSSN get; set; 

/****************View Specific Properties****************************/
public SelectList SLLanguages  get; set; 

【讨论】:

以上是关于向 POCO 添加方法或创建单独的类来更新 POCO 的值是一种好习惯吗?的主要内容,如果未能解决你的问题,请参考以下文章

直接使用提交过来的类来更新字段EntityState.Modified并过滤null值的方法

如何创建像laravel这样的类来连续调用类方法

POCO 模型和计算字段

如何覆盖或向单独类中的方法添加属性,以便刷新 WCF 服务不会影响我的更改?

使用 OrmLite,有没有办法在我的 POCO 被修改时自动更新表模式?

使用 DocumentListener 实现检查 JTextField