How to implement custom functionality in a model in .NET?

2

I needed to implement some functionality in the users model but as you can see right at the beginning this class is automatically generated by Entity, so whenever I update or recreate the model the custom functionality will be lost.

Example of a custom implementation done in the users model:

public string full_name
{
    get
    {
        return this.first_name + ' ' + this.last_name;
    }
}

Is there any way I can override the model to keep these features customized without being overwritten whenever I update / rebuild the model?

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace E_Learning.Models
{
    using System;
    using System.Collections.Generic;
    using E_Learning.Helpers;

    public partial class users
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public users()
        {
            this.updated_at = DateTime.Now;
            this.created_at = DateTime.Now;

            this.signatures = new HashSet<signatures>();
            this.testimonials = new HashSet<testimonials>();
        }

        public int id { get; set; }
        public string identity_ { get; set; }
        public string first_name { get; set; }
        public string last_name { get; set; }
        public string email { get; set; }
        public string telephone { get; set; }
        public string password { get; set; }
        public Nullable<System.DateTime> birthday { get; set; }
        public Nullable<int> sexuality { get; set; }
        public string remember_token { get; set; }
        public System.DateTime updated_at { get; set; }
        public System.DateTime created_at { get; set; }
        public Nullable<byte> status { get; set; }
        public string handle { get; set; }

        public string setHandle ()
        {
            return Slugify.Make(this.first_name + ' ' + this.last_name);
        }

        public string full_name
        {
            get
            {
                return this.first_name + ' ' + this.last_name;
            }
        }

        private Nullable<int> age
        {
            get
            {
                DateTime now = DateTime.Today;

                if (this.birthday.HasValue)
                {
                    DateTime birthday = DateTime.Parse(this.birthday.ToString());
                    int age = now.Year - birthday.Year;

                    if (now < birthday.AddYears(age))
                        age--;

                    return age;
                }

                return null;
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<signatures> signatures { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<testimonials> testimonials { get; set; }
    }
}

Print:

    
asked by anonymous 04.05.2016 / 16:04

3 answers

3

This has been more or less answered at How to edit a Partial Class?

Partial classes exist precisely for this type of problem. You create the customizations in a separate file that will be compiled together.

Of course you can not touch anything of the generated file. This will always be lost when updating the model . You have to find an organization and even create design patterns to decouple one part of the other if you have some more complex things to do (in most cases you just have simple methods anyway).

Then I created another file with class partial Users and do whatever you need there. Note that the class has already been generated with this intent.

You can not overlap an existing property. What you can do is create another one that calls the original created by EF. Only EF property will be persisted, yours will be helpful. It may not be ideal, but as far as I know it has no other way. In your example, it will work perfectly, FullName is an excellent complement property for FirstName and LastName .

Depending on what you do, you can add add-ons for the template generated in a metadata class . It does not seem to be what you want, but it is an alternative in some cases.

If you can wait for C # 7, you may have supersedes . I believe it is tailor made for this problem. So you can say in the partial class that one property should override another generated in the other part of the class, but less like a virtual method (of course the mechanism is much simpler and solved all in compilation).

An example is the use of events: Partial for separating events and methods . Example with WPF: Centralize (use only one) one try-catch for every WPF application . Example with ASP.Net: Error while adding While value in List < >

It can help: Create partial method in C #

Another solution is to adopt the Model First that ends this problem and is the future of EF.

    
04.05.2016 / 16:36
2

To do this, you can create a ViewModels project in your application, and add a metadata that associates with your Entity Model. Example:

namespace E_Learning.ViewModels
{
    [MetadataType(typeof(E_Learning.Models.users))]
    public partial class users
    {

    }
}

Reference: link

    
04.05.2016 / 16:53
2

One of the principles of object-oriented programming, SOLID, is that an object must be closed for maintenance, but open for extension.

To add functionality to a closed object for maintenance, simply extend it. See:

public static class UserExtensions
{
    public static string FullName(this user user) =>        
         $"{user.first_name} {user.last_name}";
}

And then just consume:

var usuario = new user { first_name = "Thiago", last_name = "Lunardi" };
Console.WriteLine( usuario.FullName() ); // Thiago Lunardi

See more in this article on SOLID - OCP - Open / Closed Principles .

    
04.05.2016 / 16:35