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

Is it a good practice to add methods to the POCOs or to create separate class to update the values of the POCOs?

向 POCO 添加方法或创建单独的 class 以在我们需要时更新 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 或 return 数据到视图。有时我需要在将 object 发送到视图之前更新一些属性,例如上面示例中名为 Roles 的列表,所以我想知道是否应该将方法添加到 POCO class 还是创建一个 class 来更新属性更好?

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

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

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

Here是对这个问题的回答:

A POCO is not a DTO. POCO stands for Plain Old CLR Object, or Plain Old C# Object. It’s basically the .Net version of a POJO, Plain Old Java Object. A POCO is your Business Object. It has data, validation, and any other business logic that you want to put in there. But there’s one thing a POCO does not have, and that’s what makes it a POCO. POCOs do not have persistence methods. If you have a POCO of type Person, you can’t have a Person.GetPersonById() method, or a Person.Save() method. POCOs contain only data and domain logic, no persistence logic of any kind. The term you’ll hear for this concept is Persistence Ignorance (PI). POCOs are Persistence Ignorant.

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

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

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

您的 POCO(系统 )应该是精简的,功能(系统 做的 )应该包含您的 POCO 进行交互。如果你努力让它保持那么简单,你将能够摆脱今天称为 OO 但实际上是 class 方向的无穷无尽的抽象和限制,从而在软件设计中产生如此多的问题。甚至多态性(现代 GOTO)也将消失,使系统行为优先 class.

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