16

Is it a good practice to add methods to the POCOs or to create separate class to update the values of the POCOs in case we need that?

For example,

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

I use it just to hold the data to update the model entity or to return data to the view. Sometimes I need to update some properties before I send the object to the view, like the list called Roles in the above example, so I am wondering about if I should add the methods to the POCO class or is it better to create a class to update the properties?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mo Haidar
  • 3,748
  • 6
  • 37
  • 76
  • 1
    possible duplicate of [Adding methods to POCO classes](http://stackoverflow.com/questions/8535199/adding-methods-to-poco-classes) – Bjørn-Roger Kringsjå Aug 16 '15 at 14:59
  • Please review http://stackoverflow.com/questions/4915957/using-system-componentmodel-dataannotations-with-entity-framework-4-0/ regarding the annotations and possibly use the meta class re: answer by Austin Lamb of the Silverlight team at MS. Although I have seen some comments elsewhere about the meta class it does seem reasonable for POCO objects to me. – Mark Schultheiss Aug 16 '15 at 15:41

5 Answers5

17

Here is an answer to this question:

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.

I prefer to read the whole article, not just to get the answer to your question, but also understand the difference between the POCO and DTO.

Mo Haidar
  • 3,748
  • 6
  • 37
  • 76
5

In that case the POCO has a ViewModel role, and as such, IMHO, it should just be a Data Transfer Object (DTO) and have just the bare minimum code.

Could be some validation methods, may be some basic calculation among the properties and that should be it.

Miguel Veloso
  • 1,055
  • 10
  • 16
2

Your class looks more like a data specification, hence should remain as such. Separate the behavior from the model in this case.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Migg
  • 464
  • 5
  • 13
2

This problem is what DCI is used for to solve, by separating the simple POCO/data objects from the functionality.

If the data will update in some kind of process as you describe, in DCI you model that process as a Context, based on a user mental model, not on some abstraction like a service, facade or any other engineer design pattern that effectively disconnects the user from the system and spreads the actual functionality across the system.

Your POCOs (what the system is) should be lean, the functionality (what the system does) should contain what's needed for your POCOs to interact. If you strive to keep it that simple, you'll be able to do without the endless abstractions and limitations of what today is called OO but is really class-orientation, creating so many problems in software design. Even polymorphism (modern day GOTO) will be gone, making system behavior first class.

ciscoheat
  • 3,719
  • 1
  • 35
  • 52
0
//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; }
}
Chef_Code
  • 241
  • 4
  • 11