Professional Documents
Culture Documents
EntityFramework nos provee tres enfoques o tres formas para crear nuestro modelo conceptual o modelo de dominio, los cuales describo a continuacin: 1. DataBase First: Permite obtener un modelo basado en una base de datos existente, todas las clases del modelo sern generadas automticamente a travs de plantillas de generacin de cdigo T4, digamos que este flujo es muy comn ya que solemos modelar en primera instancia nuestra base de datos y a lo largo del proyecto trabajamos sobre ella, nuestro modelo generado quedar almacenado en un archivo con extensin .edmx y este se podr ver y editar en un diseador, para actualizar nuevos cambios que surjan en nuestra base de datos. 2. Model First: En este enfoque creamos en primera instancia nuestro modelo conceptual a travs de un Entity Data Model, y posteriormente basados en este modelo creamos nuestra base de datos, una ventaja de este enfoque es que nos concentramos en el dominio de nuestra aplicacin y EF se encarga de crear la base de datos con la informacin que consignamos en el modelo. 3. Code First: Con este enfoque nos salimos un poco de lo normal, en este caso primero codificamos nuestras clases de dominio o clases POCO y luego basados en ellas creamos nuestro modelo y base de datos, solo debemos crearlas y hacer uso de DBContext y DBSet para cada clase que se creara en nuestra base de datos, para manejar las actualizaciones en nuestra DB tenemos DataBase Migrations que nos permite actualizar los cambios sobre nuestras clases. Bueno ahora que conocemos los diferentes enfoques que nos permite EntityFramework para crear nuestro modelo conceptual, me imagino que elegir uno u otro radica mucho en nuestros gustos y costumbres como desarrolladores, sin embargo tambin existe un factor que puede influir y es el insumo con el que contemos en el momento, es decir, si ya contamos con una base de datos creada por ejemplo, o si tenemos un modelo establecido o si simplemente ya tenemos unas clases creadas, lo importante es que sepamos que para cada uno de estos casos EF nos ofrece una solucin, con esto podemos ahorrar bastante trabajo segn sea nuestro caso. Por ultimo les quiero compartir una grfica que he encontrado que podra resumir este artculo:
Bueno amigos espero este artculo les sea de utilidad a la hora de elegir un enfoque de EntityFramework, en prximos artculos veremos en detalle cada uno de los enfoques y su implementacin.
enfoques para ver ms en detalle cada uno de ellos, en primera instancia vamos a iniciar con Data Base First, que como haba mencionado nos permite generar automticamente nuestro modelo y nuestras clases Poco, teniendo como punto de referencia una base de datos previamente creada. Pues veamos cmo podemos lograr esto: Para nuestro ejemplo vamos a trabajar con la famosa base de datos Northwnd, de la cual comparto un .bk para que puedan seguir paso a paso la demo: Northwnd DB Una vez restauremos la base de datos, generamos nuestro EntityDataModel, que generar nuestro modelo conceptual y las clases poco que estarn mapeadas a l, para esto seguimos los siguientes pasos: 1. En nuestro proyecto que puede ser una librera de clases, sitio web, consola, etc. Oprimimos clic derecho y elegimos la opcin agregar nuevo elemento, posteriormente filtramos los tipos de elementos por datos y por ultimo elegimos ADO.NET Entity Data Model y hacemos clic sobre el botn agregar, no sin antes darle un nombre a nuestro modelo:
2. Posteriormente nos muestra dos opciones, la primera para generar desde una base de datos existente y la otra para crear un modelo en blanco, en nuestro caso seleccionamos la primera para crear desde nuestra DB Northwnd:
3. Ahora debemos especificar los datos de conexin a nuestra base de datos, para esto hacemos clic en el botn "Nueva conexin", luego vemos como se genera una cadena de conexin y podemos elegir si mostrarla en el archivo de configuracin de nuestro proyecto o no:
4. Una vez lista nuestra conexin podemos elegir que versin de EntityFramework vamos a usar, para nuestro ejemplo usaremos la versin 6 que es la ltima versin recientemente liberada:
5. Y para finalizar, debemos elegir los elementos de nuestra base de datos que queremos que sean incluidos en nuestro modelo:
Y nuestro resultado final es el modelo que visualizamos de inmediato, con sus respectivas relaciones, procedimientos almacenados y funciones si es que los seleccionamos para incluir, todo esto representado en un archivo con extensin .edmx, el cual si exploramos bien contiene el diagrama y adems todas las clases auto generadas que corresponden a las tablas en nuestras base de datos:
Bueno amigos eso es todo por esta ocasin. Con esto damos inicio a EntityFramework DB First, en prximos artculos profundizaremos ms acerca de este modelo que generamos y como interactuar con el para el acceso a datos de nuestras aplicaciones, espero les sea de utilidad.
[EntityFramework] Mralo tan fcil como quieras! dividiendo en colores tu modelo conceptual
Como todos sabemos, en proyectos de gran tamao, tambin tenemos por lo general un modelo de datos de gran tamao, y que tiende a crecer con el tiempo, esto sin lugar a dudas se vuelve demasiado engorroso a la hora de comprender el diagrama y a la hora de buscar tablas y relaciones que corresponden a cierta incumbencia del sistema. Pero bueno, despus del problema ahora veamos una de las soluciones que nos plantea EntityFramework al respecto: En EF podemos hacer mucho ms amigable visualmente nuestro modelo, pintndolo y dividindolo por colores, por ejemplo podramos colorear de verde las tablas correspondientes a seguridad, o de naranja las tablas correspondientes a las ventas y as para cada segmento de tablas, ahora veamos cmo podemos hacer esto y que tan sencillo es: Solo basta con elegir la tabla o las tablas que deseamos pintar de cierto color, abrimos el cuadro de propiedades(f4) y establecemos la propiedad FillColor seleccionando del ColorPicker el color que queremos, y as para cada tabla, de esta forma nos encontramos con un modelo divido y agrupado estratgicamente y de mucha ms fcil compresin. Eso es todo, espero que este sencillo truco les sea de utilidad a la hora de ordenar mejor su modelo.
generadas y ahora tengamos que acceder de forma diferente a ellas, es solo una separacin visual valga la aclaracin. Entonces una buena practica sera tener un diagrama principal en el cual tengamos nuestro modelo completo, y tener sub diagramas que nos modelen ciertas incumbencias del negocio, entonces podramos tener un sub diagrama para ventas, otro para clientes, otro para proveedores y as, segn lo necesitemos. Pero bueno veamos cmo podemos hacer esto en la prctica: Lo primero que debemos hacer es clic derecho sobre nuestro modelo y elegir Model Browser, con esto se nos despliega una pestaa en cual podemos ver los diagramas, las entidades del modelo y la base de datos.
Ahora en la carpeta Diagrams hacemos clic derecho y elegimos la opcin "add new Diagram", con esto tenemos una plantilla en blanco, sobre la cual podemos arrastrar todas nuestras entidades para formar el diagrama que queremos.
De esta forma podemos crear los diagramas que queremos y podremos comprender y tener mayor enfoque cuando requiramos analizar el modelo correspondiente a alguna parte en especfico de nuestro sistema, adicional hay una caracterstica que vale la pena resaltar y es que si hacemos clic derecho sobre una de las entidades y elegimos la opcin: "Include Related" se nos traern al diagrama todas las entidades que tienen relacin con esta, muy til por cierto para formar el diagrama con mayor rapidez.
Y para finalizar quisiera recomendarles tener precaucin al eliminar una entidad de algn diagrama, ya que si no nos fijamos bien podemos eliminar la entidad como tal de nuestro modelo, es decir eliminar la clase y cuando sincronicemos con la base de datos eliminaramos la tabla, y hablo de cuando la eliminamos a travs de la tecla suprimir, entonces les recomiendo usar shift + suprimir, si lo quieren hace por teclado o haciendo clic derecho sobre la entidad y eligiendo la opcin "Remove from diagram".
Y bueno eso es todo por hoy, espero que les sea de gran utilidad para ordenar y hacer ms legibles sus diagramas.
Con esto se nos abrir una ventana que contiene tres pestaas la primera con ttulo agregar, la segunda actualizar y la tercera eliminar, y como su nombre lo indica en la pestaa agregar encontramos todos los elementos que se han agregado a la base de datos y que an no estn
mapeados a nuestro modelo o aquellos objetos que no se seleccionaron cuando se decidi crear el modelo basado en la DB:
En la segunda pestaa encontraremos todo aquellos objetos que se actualizarn con la sincronizacin, es decir aquellos que ya estn mapeados con la base de datos, se actualizarn para obtener cambios que an no se han mapeado:
Y por ltimo en la tercer pestaa encontramos todos aquellos objetos que se decidieron eliminar de nuestro modelo, esto quiere decir que los elementos que seleccionemos en esta pestaa se borraran tambin de la base de datos, por eso debemos tener especial cuidado con esta pestaa, ya que pudimos haber eliminado alguna entidad de nuestro modelo sin darnos cuenta:
Bueno y para efectuar la sincronizacin hacemos clic sobre el botn "Terminar", esperamos unos segundos y enseguida podemos ver todos los cambios que realizamos en la base de datos actualizados en nuestro modelo.
Y eso es todo, una manera bastante simple y gil para sincronizar nuestro modelo con nuestra base de datos, espero les sea de utilidad.
Enseguida se nos muestra la pestaa de "Mapping Detailts" en dnde encontraremos tres secciones, una para mapear un procedimiento para insercin, otra para mapear un procedimiento de actualizacin y por ultimo una para mapear un procedimiento de eliminacin, podemos usarlas todas o solo las que necesitemos segn sean nuestras necesidades, y cuando elijamos el SP que deseamos mapear enseguida se desplegarn sus parmetros y adicional podemos especificar bindings para los resultados, tal y como se muestra en la siguiente imagen:
Para terminar de mapear nuestro procedimiento almacenado, guardamos los cambios realizados en el modelo y listo! ahora podemos ver el SP mapeado como una funcin en el Model Browser:
Mapear una funcin a un procedimiento almacenado: Tambin podemos mapear una funcin de EF a un procedimiento almacenado directamente, y podemos manejar varios valores de retorno, para esto debemos hacer clic derecho sobre nuestro modelo sin tocar una entidad y elegir la opcin "Add New" / "Function Import" tal y como se muestra en la imagen:
Como vemos en primera instancia debemos especificar el nombre que va a tener nuestra funcin, debajo tenemos una casilla de verificacin "Function import is composable", que nos permite indicar si vamos a trabajar con un SP o con una funcin de sql server, y dependiendo de esta seleccin en el siguiente listado se mostraran todos procedimientos almacenados o todas las funciones que tengamos en nuestra base de datos, obviamente debemos seleccionar una. Ahora vamos a ver que opciones tenemos para retornar en nuestra funcin: None: Indica que la funcin no tendr valor de retorno. Escalars: Indica que la funcin retornara un valor escalar, es decir un solo valor, el cual puede ser de diversos tipos los cuales podemos ver si seleccionamos esta opcin. Complex: Indica que la funcin retornara un tipo complejo o Complex type, de este tipo
hablaremos ms adelante, pero bsicamente es un tipo que puede contener campos de varias entidades por ejemplo, o incluso campos que no corresponden a las entidades como valores calculados, si seleccionamos esta opcin podemos seleccionar un tipo complejo que ya tengamos creado, o tambin lo podemos crear en esta misma ventana a travs de la opcin "Create new Complex Type" que explicar ms adelante. Entities: Indica que se va a retornar una entidad de nuestro modelo. Y por ltimo tenemos la seccin de informacin de columna, donde si hacemos clic en la opcin "Get Column Information" podremos ver el detalle de cada columna que devuelve el procedimiento almacenado, si es que devuelve alguna columna, y es a esto cuando me refera a crear un Complex type desde esta misma ventana, ya que si hacemos clic en la opcin "Create new Complex Type" automticamente se crear un tipo complejo para la estructura de columnas que devuelve el SP. Mapear la funcin al procedimiento almacenado a travs del Model Browser: Bueno y por ultimo tambin podemos hacer el mapeo del procedimiento almacenado desde el model browser, haciendo clic derecho en la carpeta "Function Imports" y eligiendo la opcin "Add function import", tal y como se ve en la imagen:
Y posteriormente se nos muestra la misma ventana explicada anteriormente. Bueno y con esto damos por terminado nuestro artculo acerca del uso de procedimientos almacenados en EntityFramework, espero les sea de gran utilidad y veamos que no se trata de comparar EF vs Stored procedures como me han preguntado algunas personas, si no de usarlos en conjunto para obtener un ptimo desempeo.
cmo podemos lograrlo: Lo primero que debemos hacer es abrir nuestro modelo, y abrir el Model Browser, en el cual encontraremos una carpeta llamada Enum types, sobre la cual haremos clic derecho y elegiremos la opcin "Add New Enum type", tal como se muestra en la imagen:
Enseguida se nos mostrara la siguiente ventana, en la cual debemos especificar las constantes que tendr nuestra enumeracin:
En primera instancia debemos especificar el nombre que tendr la enumeracin, y el tipo del cual heredara si Int 16, 32 64, Byte o SByte esto segn la longitud de los nmeros que se vayan a asignar a las constantes. Y posteriormente debemos indicar cul ser el listado de constantes de la enumeracin y que valor le corresponder a cada una, y ya con esta informacin podemos terminar la creacin del enum, sin embargo en la ltima parte del cuadro de dialogo tenemos dos opciones ms, las cuales explicar a continuacin: Set Flags attribute: Como todos sabemos o si no lo sabes an te contextualizo, cuando creamos a travs de cdigo una enumeracin la podemos decorar con el atributo [Flags], esto indica que la enumeracin podr manejar combinaciones, es decir se puede asignar su valor con ms de una opcin, yo podra asignar como valor, en nuestro caso por ejemplo los valores TarjetaCredito y TarjetaDebito que en cdigo C# sera algo como esto:
FormaPago formPago = FormaPago.TarjetaCredito | FormaPago.TarjetaDebito; Reference external type: Adems de crear una nueva enumeracin tambin podemos usar una ya existente, para eso este campo, en el cual debemos especificar el NameSpace y el nombre del enum, para que sea usado por EntityFramework. Y listo para crear nuestra enumeracin oprimimos el botn OK, y ya tenemos nuestro enum creado para ser utilizado, ahora podemos hacer clic en cualquiera de los campos de cualquier entidad y abrimos el cuadro de propiedades correspondiete(F4) y en el campo "type" veremos que ya podemos escoger como tipo la enumeracin que acabamos de crear:
Bueno y con esto damos por terminado nuestro artculo acerca del cmo trabajar con enumeraciones en EntityFramework, espero les sea de gran utilidad y ya queda criterio propio como explotar todas las ventajas que nos ofrece.
Como podemos ver, para ambos se muestran los mismos tipos respectivamente, y creo que hasta aqu surge otra interrogante, Cul es la diferencia entre Geography y Geometry entonces? respondamos a esta pregunta definiendo cada uno: Geography: Tipo de dato espacial que tiene la capacidad de almacenar datos elipsoides como lo son por ejemplo la coordenadas de latitud y longitud. Geometry: Tipo de dato espacial que tiene la capacidad de almacenar un sistema de coordenadas plano. Y adicional cito esta definicin:
Geometry and Geography are a bit different. Geometry deals with planar data. Geometry is well documented under the Open Geospatial Consortium (OGC) Specification. Geography deals with ellipsoidal data, taking in mind the curvature of the earth when performing any calculations. SQL introduced spatial support for these two types in SQL Server 2008. The SQL implementation supports all of the standard functions outlined in the OGC spec.
Y bueno amigos eso es todo, espero les sea de utilidad y puedan tener un recurso del cual echar mano cuando se les presente algn requerimiento en algn sistema con respecto a manejo de informacin espacial. Adicional les quera compartir estas referencias, por si quieren profundizar ms acerca del tema: Tipos espaciales en EntityFramework Spatial types in the EntityFramework
agrupa todos los objetos de nuestro modelo conceptual, bueno para code first es igual y es el primer objeto que debemos crear para generar nuestra base de datos, entonces en el constructor de nuestro contexto podemos pasar como parmetro el nombre que queremos darle a la DB una vez se cree, o tambin podemos pasar como parmetro la cadena de conexin para nuestra DB, o simplemente no enviamos parmetros en el constructor y siendo as code first auto generar el nombre usando el name space en cual se encuentra el contexto y el nombre de la clase del mismo, algo como eso: NameSpace.ContextClassName Y para crear tablas con sus respectivas primary y foreign key y dems objetos usa algunas convenciones, las cuales podemos encontrar en el siguiente enlace: Code First Conventions Adicional quiero compartirles esta imagen que resume el proceso de creacin de la base de datos:
Y para terminar quiero compartirles un par de conceptos fundamentales a la hora de trabajar con Code first y que vamos a ver muy a menudo en nuestra serie de artculos de Code First: DbContext: Ser el objeto que agrupar todos los elementos de nuestro modelo conceptual y manejar el mapeo de cada uno ellos con su par en la base de datos, incorpora el patrn unidad de trabajo y el patrn repositorio, aqu les dejo la referencia de msdn: DbContext DbSet: Comnmente usado como tipo de propiedades al interior de una clase que hereda del tipo DbContext, este recibe un tipo genrico el cual representa una entidad de nuestro dominio, de esta forma habilita las operaciones CRUD para la entidad especificada. Aqu les dejo la referencia de msdn: DbSet DataAnotations: Serie de atributos con los cuales se pueden decorar las entidades del dominio y sus propiedades, permiten especificar caractersticas como longitud, exclusiones e mapeo, primary y foreign key, etc. Aqu les dejo la referencia de msdn: Code First Data Annotations DataBase Migrations: Permite actualizar nuestra base de datos cuando existan cambios en
nuestras entidades de dominio. Aqu les dejo la referencia de msdn: DataBase Migrations Bueno y eso es todo, espero esta introduccin a Entity Framework Code First sea de gran utilidad para ustedes y despeje muchas dudas, en artculos posteriores veremos ms en detalle la forma de trabajo e implementacin. Saludos y buena suerte!
1: 2: 3: 4: 5: 6: 7: 8: 1: 2: 3: 4: 5: 6: 7: 8:
public class Producto { public int Id { get; set; } public string Nombre { get; set; } public string Descripcion { get; set; } } public class Categoria { public int Id { get; set; } public string Nombre { get; set; } public string Descripcion { get; set; } }
Perfecto esas clases tan simples sern las entidades de dominio con las que trabajaremos en nuestro ejemplo, ahora vamos a habilitar estas entidades para que a travs de ellas podamos en primera instancia crear nuestra base de datos y posteriormente interactuar entre dominio y DB mediante el mapeo generado, para esto creamos un contexto el cual contenga propiedades de tipo DBSet<T> para cada entidad:
1: 2: 3: 4: 5: 6:
7: 8: 9: 10: 11:
public DbSet<Producto> Productos { get; set; } public DbSet<Categoria> Categorias { get; set; } }
Y listo, con esto tenemos una infraestructura bsica para lograr crear nuestra base de datos basados en las entidades de dominio que creamos, un aspecto a tener en cuenta en el contexto que acabamos de crear es que estamos pasando como parmetro al constructor el nombre que va a tener nuestra base de datos, y es importante especificar la cadena de conexin en el archivo app.config de nuestro proyeto, para tener los datos de conexin al servidor:
class Program { static void Main(string[] args) { using (var contexto = new Context()) { var producto = new Producto {Id = 1, = "Jabn", Descripcion = "Producto para el aseo del }; contexto.Productos.Add(producto); contexto.SaveChanges(); } } }
Ahora ejecutamos para probar, y efectivamente vemos que se ha creado nuestra base de datos, con el nombre que indicamos en el constructor, tal cual con la estructura de nuestra entidades y adems se ha agregado el producto que indicamos en la tabla Productos, como podemos observar si depuramos la primer vez que ejecutamos la app se demora un tiempo considerable en agregar el producto ya que en ese momento no existe la Db y por lo tanto se crea, pero en las ejecuciones que hagamos en adelante el tiempo ser muy corto. Bueno y con esto damos por terminado nuestro ejemplo de cmo crear nuestra base de datos basados en un contexto previamente creado, sin embargo surgen algunas dudas como: Cmo se logran crear relaciones de diferentes tipos entre las tablas? Cmo doy longitud a los
campos de la tabla y dems caractersticas? pues bien en prximos artculos iremos profundizando y explicando estos temas, espero les sea de utilidad.
[Table("Productos")] public class Producto { [Key] public int Codigo { get; set; } [Required] [Column("Nombre", TypeName = "varchar", Order = 2)] public string Nombre { get; set; } [MaxLength(100), MinLength(10)] public string Descripcion { get; set; } [NotMapped] public string CodigoIso { get; set; } } Cmo podemos ver decoramos la propiedad Codigo con el atributo [Key] con esto le estamos diciendo a Entity Framework que esta ser la clave primaria de la tabla, y podemos ver una serie de atributos que hemos usado y que explicare a continuacin:
[Table("Productos")] : Permite asignar un nombre en especfico a la tabla que se generar a partir de la entidad, recordemos que si no se usa este atributo Entity Framework asume que el nombre de la tabla ser el plural del nombre de la entidad por ejemplo para la entidad Producto su tabla correspondiente recibir el nombre de Productos. [Required] : Permite indicar si un campo es requerido o no, es decir si el campo en la tabla permitir valores nulo o no, lo que conocemos como Null o Not Null. [Column] : Se usa para indicar informacin correspondiente a una columna de la tabla, su constructor posee dos sobre cargas en las cuales podemos especificar nombre de la columna en caso de que queramos especificar un nombre diferente al de la propiedad de la entidad, tipo de la columna y orden en el que aparecer en la tabla. [MaxLength] : especifica la longitud mxima del campo en la base de datos. [MinLength] : especifica la longitud mnima del campo en la base de datos. [NotMapped] : Puede darse el caso que por algn motivo no deseemos mapear alguna propiedad de alguna entidad de dominio a nuestra base de datos ya que solo la queremos tener en nuestra entidad para usarla en nuestra lgica y no queramos persistir la propiedad a la base de datos. Este atributo nos ayuda con esto, cuando EF encuentre alguna propiedad decorada con este atributo simplemente la omitir y no la tendr en cuenta para la creacin de la DB. Bueno y con esto damos por terminado nuestro artculo de como configurar nuestras entidades de dominio a travs de Data Annotations. Cmo mencione antes existe otra forma de hacer la configuracin y es a travs de Fluent Api, tema que trataremos en el prximo artculo de esta serie de Entity Framework Code First, espero les sea de inters y utilidad. Para observar todos los Data Annotatiosn disponibles revisar la documentacin del name space System.ComponentModel.DataAnnotations
{ public Context() : base("Productos") { } public DbSet<Producto> Productos { get; set; } public DbSet<Categoria> Categorias { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { // Aqu haremos nuestras configuraciones con Fluent API. base.OnModelCreating(modelBuilder); } } Cmo vemos ahora el mtodo OnModelCreating recibe el parmetro modelBuilder de tipo DbModelBuilder, es con esta clase que lograremos hacer todas las configuraciones que necesitamos, ahora s vamos a ver como lograr dichas configuraciones, las cuales haremos sobre la entidad Producto, la cual usamos en nuestro ejemplo anterior de Data Annotations:
[Table("Productos")] public class Producto { [Key] public int Codigo { get; set; } [Required] [Column("Nombre", TypeName = "varchar", Order = 2)] public string Nombre { get; set; } [MaxLength(100), MinLength(10)] public string Descripcion { get; set; } [NotMapped] public string CodigoIso { get; set; } } Ahora homologaremos todo lo que hicimos con Data Annotations a travs de Fluent Api, de la siguiente manera:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { // Aqu haremos nuestras configuraciones con Fluent API. // Especificar el nombre de una tabla. modelBuilder.Entity<Producto>().Map(m => m.ToTable("Productos")); // establecer una primary key. modelBuilder.Entity<Producto>().HasKey(c => c.Codigo); // Definir un campo como requerida. modelBuilder.Entity<Producto>().Property(c => c.Nombre).IsRequire d();
// Definir el nombre de un campo. modelBuilder.Entity<Producto>().Property(c => c.Nombre).HasColumn Name("Nombre"); // Definir el tipo de un campo. modelBuilder.Entity<Producto>().Property(c => c.Nombre).HasColumn Type("varchar"); // Definir el orden de un campo. modelBuilder.Entity<Producto>().Property(c => c.Nombre).HasColumn Order(2); // Definir el mximo de caracteres permitidos para un campo. modelBuilder.Entity<Producto>().Property(c => c.Descripcion).HasM axLength(100); // indicar que no se debe mapear una pripiedad a la base de datos . modelBuilder.Entity<Producto>().Ignore(c => c.CodigoIso); base.OnModelCreating(modelBuilder); } Como podemos ver, hemos homologado las instrucciones de primary key, nombres, requerido y dems caractersticas a travs de Fluent Api, con esto podramos quitar los Data Annotations de nuestra entidad de dominio Producto, y una vez se inicialice la base de datos se tendrn en cuenta las configuraciones especificadas en el mtodo OnModelCreating. Para terminar con el artculo quisiera darles un tip, para el trabajo con Code First Fluent Api, de una forma ms ordenada, ya que como vemos la codificacin en el mtodo OnModelCreating puede crecer bastante ya que all va la configuracin para cada entidad, por esto una buena prctica es separar en clases la configuracin de cada entidad, con esto logramos un cdigo ms ordenado y ms reutilizable, ahora veamos cmo hacerlo: Para esto slo debemos crear una clase que herede de EntityTypeConfiguration<T> y en el constructor de esta clase codificar las configuraciones tal y como lo hicimos en el mtodo OnModelCreating, cmo se muestra a continuacin:
public class ProductoMappings : EntityTypeConfiguration<Producto> { public ProductoMappings() { // Especificar el nombre de una tabla. this.Map(m => m.ToTable("Productos")); // establecer una primary key. this.HasKey(c => c.Codigo); // Definir un campo como requerida. this.Property(c => c.Nombre).IsRequired(); // Definir el nombre de un campo. this.Property(c => c.Nombre).HasColumnName("Nombre"); // Definir el tipo de un campo. this.Property(c => c.Nombre).HasColumnType("varchar");
// Definir el orden de un campo. this.Property(c => c.Nombre).HasColumnOrder(2); // Definir el mximo de caracteres permitidos para un campo. this.Property(c => c.Descripcion).HasMaxLength(100); // indicar que no se debe mapear una pripiedad a la base de datos . this.Ignore(c => c.CodigoIso); } } Haramos estos para cada entidad, y en el mtodo OnModelCreating slo agregaramos la configuracin que acabamos de crear, de la siguiente forma:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { // Aqu haremos nuestras configuraciones con Fluent API. modelBuilder.Configurations.Add(new ProductoMappings()); base.OnModelCreating(modelBuilder); } Y para despedirme quisiera anotar que un mtodo de configuracin no excluye al otro, es decir podramos usar configuracin a travs de Data Annotations y tambin a travs de Fluent Api sin ningn problema. Y bueno eso es todo espero les sea de utilidad y de inters este tema de configuracin de entidades de dominio a travs de Entity Framework Code First Fluent Api.
public class Categoria { public int Id { get; set; } [MaxLength(100)] public string Nombre { get; set; } [MaxLength(200)] public string Descripcion { get; set; } [Required] public virtual Producto Producto { get; set; } }
Entonces para nuestro ejemplo supondremos que un producto solo puede tener una categora, y para configurar la relacin a travs de Data Annotations hacemos lo siguiente:
[Table("Productos")] public class Producto { [Key] public int Codigo { get; set; } [Required] [Column("Nombre", TypeName = "varchar", Order = 2)] public string Nombre { get; set; } [MaxLength(100), MinLength(10)] public string Descripcion { get; set; } [NotMapped] public string CodigoIso { get; set; } [ForeignKey("Categoria")] public int IdCategoria { get; set; } public virtual Categoria Categoria { get; set; } } Como podemos ver en nuestra entidad Producto creamos una propiedad de tipo entero llamada IdCategoria, y la decoramos con el atributo ForeignKey el cual nos indica que esta propiedad nos servir para relacionarla con otra entidad, y vemos que en su constructor especificamos la palabra "Categoria", que hace alusin a la propiedad virtual que nos sirve para configurar la relacin con la entidad Categoria, de esta forma una vez se cree la base de datos se creara la relacin de uno a uno. Para probar esto podemos crear una aplicacin de consola y escribir el siguiente cdigo en la clase Program:
class Program { static void Main(string[] args) { var categoria = new Categoria { Id = 1, Nombre = "Lacteos", Descr ipcion = "Productos lacteos" }; var producto = new Producto { Codigo = 1, Nombre = "Leche", Descr ipcion = "Producto Lacteo", Categoria = categoria }; using (var contexto = new Context()) { contexto.Productos.Add(producto); contexto.SaveChanges(); } } } Y observaremos que tan slo agregando el producto a la base de datos tambin se agregara la categora correspondiente en su respectiva tabla y con sus relaciones correspondientes. Ahora vamos a ver como lo podemos hacer pero esta vez usando Fluent Api.
Relacin de uno a uno mediante Fluent Api: Para configurar la relacin a travs de Fluent Api, creamos una clase de configuracin para la entidad Categoria o lo hacemos directamente en el contexto como vimos en el artculo Configurando nuestras entidades de dominio con Fluent Api:
public class CategoriaMappings : EntityTypeConfiguration<Categoria> { public CategoriaMappings() { // Crear relacin con la entidad Producto. this.HasRequired(c => c.Producto).WithRequiredPrincipal(e => e.Ca tegoria); } } Como vemos homologamos el cdigo planteado anteriormente con Data Annotations, indicando que en la entidad categora se requiere un producto y de igual forma en la entidad productos se requiere una categora. Y bueno amigos, eso es todo, espero les sea de utilidad y de inters este post acerca de relacin uno a uno en Entity Framework code First, en prximos artculos observaremos cmo configurar otros tipos de relaciones.
[Table("Productos")] public class Producto { [Key] public int Codigo { get; set; } [Required] [Column("Nombre", TypeName = "varchar", Order = 2)] public string Nombre { get; set; } [MaxLength(100), MinLength(10)] public string Descripcion { get; set; } [NotMapped] public string CodigoIso { get; set; } [ForeignKey("Categoria")] public int IdCategoria { get; set; }
public virtual Categoria Categoria { get; set; } } Cmo ven agregamos IdCategoria y especificamos que se trata de la clave fornea con respecto a la entidad categoria, de igual forma agregamos la propiedad Categoria de tipo Categoria que representa la relacin, y a continuacin en nuestra entidad Categoria agregaremos una coleccin de tipo Producto para indicar que una categora puede tener uno o muchos productos:
public class Categoria { [Key] public int Id { get; set; } [MaxLength(100)] public string Nombre { get; set; } [MaxLength(200)] public string Descripcion { get; set; } [Required] public virtual ICollection<Producto> Producto { get; set; } } Y con esto tenemos configurada nuestra relacin de una a muchos entre Productos y Categoras a travs de Data Annotations, ahora para probar la configuracin podemos crear una app de consola y copiar el siguiente cdigo en la clase program:
class Program { static void Main(string[] args) { var categoria = new Categoria { Id = 1, Nombre = "Lacteos", Descr ipcion = "Productos lacteos" }; var producto = new Producto { Codigo = 1, Nombre = "Leche", Descr ipcion = "Producto Lacteo", Categoria = categoria }; var producto2 = new Producto { Codigo = 2, Nombre = "Queso", Desc ripcion = "Producto Lacteo", Categoria = categoria }; using (var contexto = new Context()) { contexto.Productos.Add(producto); contexto.Productos.Add(producto2); contexto.SaveChanges(); } } } Relacin de uno a muchos mediante Fluent Api: Ahora vamos a configurar la relacin de uno a muchos entre Productos y Categoras, pero esta vez vamos a usar Fluent Api para lograrlo:
public class Context : DbContext { public Context() : base("Productos") { } public DbSet<Producto> Productos { get; set; } public DbSet<Categoria> Categorias { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { // Aqu haremos nuestras configuraciones con Fluent API. modelBuilder.Configurations.Add(new ProductoMappings()); modelBuilder.Entity<Producto>() .HasRequired<Categoria>(c => c.Categoria) .WithMany(c => c.Productos) .HasForeignKey(c => c.IdCategoria); base.OnModelCreating(modelBuilder); } } Cmo vemos en el mtodo OnModelCreating especificamos la relacin a travs de Fluent Api, dnde indicamos la relacin partiendo la entidad Producto e indicamos el WithMany con Categora. Y bueno amigos, eso es todo, espero les sea de utilidad y de inters este post acerca de relacin uno a muchos en Entity Framework code First, en el prximo artculo observaremos cmo configurar una relacin de muchos a muchos, para terminar con el tema de relaciones y seguir con otros temas.