none
Entidades Generadas Por EF y agregando logica de negocio RRS feed

  • Pregunta


  • Hola buenos días

    cuando uno genera las entidades en la capa de negocio busca generarlas con la herramienta Entity FrameWork ya sea con model First o con CodeFirst ExistingDatabase, esto por ayuda o no escribir todas las entidades de negocio y te las genera automáticamente,

    al mismo tiempo sirve bastante bien para la separación en capas y repositorios que ya todos saben.

    el problema es que caes en el antipatron mencionado por Martin Fowler que dice que una entidad de negocio no debe ser solo transportadora de datos y no contener lógica, o seria una entidad anemica

    a lo cual me suena muy lógica, claro que con un análisis correcto en la lógica de negocio y creando entidades que quizás ni existen los datos pero si en negocio, de echo un ejemplo muy simple seria algo así

    Este es un modelo de datos hecho en EF, y existe en la Base de datos SQL

    Este modelo genera estas clases

    public partial class PersonalRecord
        {
            public int Id { get; set; }
            public string Email { get; set; }
            public string AlternateEmail { get; set; }
            public string Name { get; set; }
            public string LastName { get; set; }
            public string MotherLastName { get; set; }
            public System.DateTime Birthday { get; set; }
            public int SexId { get; set; }
        
            public virtual Sex Sex { get; set; }
        }

    y esta otra

     public partial class Sex
        {
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
            public Sex()
            {
                this.PersonalRecords = new HashSet<PersonalRecord>();
            }
        
            public int Id { get; set; }
            public string Name { get; set; }
        
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
            public virtual ICollection<PersonalRecord> PersonalRecords { get; set; }
        }

    pero yo necesito otra clase, que será una propiedad de la clase PersonalRecord es esta

    public class TimeRange
    	{
    		private int milliSecond;
    		private int second;
    		private int minute;
    		private int hour;
    		private int day;
    		private int month;
    		private int year;
    
    
    		public int MilliSecond
    		{
    			get { return this.MilliSecond; }
    		}
    
    		public int Second
    		{
    			get { return this.second; }
    		}
    	
    		public int Minute
    		{
    			get { return this.minute; }
    		}
    
    		public int Hour
    		{
    			get { return this.hour; }
    		}
    
    		public int Day
    		{
    			get { return this.day; }
    		}
    
    		public int Month
    		{
    			get { return this.month; }
    		}
    		public int Year
    		{
    			get { return this.year; }
    		}
    
    		public TimeRange(DateTime initial, DateTime final)
    		{
    			GregorianTime time = new GregorianTime();
    			GregorianTime timeRange = time.GetGregorianTimeRange(initial, final);
    			this.milliSecond = timeRange.MilliSecond;
    			this.second = timeRange.Second;
    			this.minute = timeRange.Minute;
    			this.hour = timeRange.Hour;
    			this.day = timeRange.Day;
    			this.month = timeRange.Month;
    			this.year = timeRange.Year;
    			timeRange = null;
    			time = null;
    		}
    	}

    Esta clase no tiene razón de existir en la base de datos ya que calcula en base a dos fechas una rango de tiempo en las propiedades mostradas, en la clase PersonalRecord le agrego esa propiedad

    public class PersonalRecord 
    	{
    		public int Id { get; set; }
    		public string Email { get; set; }
    		public string AlternateEmail { get; set; }
    		public string Name { get; set; }
    		public string LastName { get; set; }
    		public string MotherLastName { get; set; }
    		public DateTime Birthday { get; set; }
    		public int IdSex { get; set; }
    
    		public virtual Sex Sex { get; set; }
    		public TimeRange Age
    		{
    			get
    			{
    				return new TimeRange(Birthday, DateTime.Now);
    			}
    		}
    	}

    Y Guala ya tengo mi entidad generada por EF con lógica de negocio, asi si tengo 100 registros en la base de datos con el campo birtday podre calcular su edad y retornarla siempre y hacer búsquedas sobre ese campo dentro de mi capa de dominio etc

    El Problema es cuando hay un cambio en la base de datos y actualiza uno las plantillas tt y actualizas las clases, Bum me

    borra toda mi lógica escrita y se perdió todo,

    ahora ya explicando toda la situación viene la pregunta

    Existe alguna forma con codefirst Database Existing de generar las clases con la herramienta y cuando cambie la base de datos

    decirlo solo puedes actualizar esto pero esto no, para que no me borre la lógica escrita por mi en las clases???

    O con otro tipo Database First Usando modelos y plantillas tt preferiría codefirst Database Existing, pero la verdad cualquier

    solución a este problema me serviría bastante

    De antemano muchas Gracias.

    viernes, 5 de enero de 2018 18:48

Respuestas

  • Es un caso bastante frecuente cuando se genera código, corres el riesgo de perder los cambios que hayas escrito sobre el archivo cuando el proceso se vuelve a repetir. La solución es sencilla: escribir el código "custom" en otra clase marcada como partial, de hecho las clases generadas, creo, ya vienen con la definición de partial.

    Partial Classes and Methods

    • Propuesto como respuesta Pablo RubioModerator viernes, 5 de enero de 2018 21:23
    • Marcado como respuesta niqel sábado, 6 de enero de 2018 3:18
    viernes, 5 de enero de 2018 19:06