framework ejemplo datos crear conexion con agregar entity-framework-4.1 code-first ef-migrations

entity-framework-4.1 - ejemplo - crear base de datos entity framework



¿Puede crear vistas de SQL/procedimientos almacenados utilizando Entity Framework 4.1 Código primer acercamiento (7)

¡El diseño de emp funciona como un campeón! Estoy usando su patrón pero también asigno procedimientos almacenados dentro de mi clase DbContext que permite simplemente llamar a esos métodos de contexto en lugar de usar SqlQuery () y llamar a los procedimientos directamente desde mi repositorio. Como las cosas pueden ponerse un poco complicadas cuando la aplicación crece, he creado una verificación dentro de mi método Seed que se asegura de que el recuento real de parámetros del procedimiento almacenado coincida con el recuento de parámetros en el método de mapeo. También he actualizado el bucle DROP emp mencionado. En lugar de tener que mantener una carpeta / archivo separado para las declaraciones de descarte, simplemente leo la primera línea de cada archivo sql y sustituyo CREATE con DROP (solo asegúrese de que la primera línea sea siempre simplemente CREATE PROCEDURE ProcName ). De esta manera, todos los procedimientos en mi carpeta StoredProcs se eliminan y se vuelven a crear cada vez que se ejecuta Update-Database. La caída también se envuelve en un bloque try-catch en caso de que el procedimiento sea nuevo. Para que el conteo de parámetros de procedimiento funcione, deberá asegurarse de envolver un bloque BEGIN/END alrededor de su tsql, ya que cada línea del archivo se lee hasta BEGIN. También asegúrese de que cada parámetro sp esté en la nueva línea.

// Drop Stored Procs foreach (var file in Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..//DataContext//SiteMigrations//StoredProcs"), "*.sql")) { // Try to drop proc if its already created // Without this, for new procs, seed method fail on trying to delete try { StreamReader reader = new StreamReader(file); // Read first line of file to create drop command (turning CREATE [dbo].[TheProc] into DROP [dbo].[TheProc]) string dropCommand = reader.ReadLine().Replace("CREATE", "DROP"); context.Database.ExecuteSqlCommand(dropCommand, new object[0]); } catch { } } // Add Stored Procs foreach (var file in Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..//DataContext//SiteMigrations//StoredProcs"), "*.sql")) { // File/Proc names must match method mapping names in DbContext int lastSlash = file.LastIndexOf(''//'); string fileName = file.Substring(lastSlash + 1); string procName = fileName.Substring(0, fileName.LastIndexOf(''.'')); // First make sure proc mapping in DbContext contain matching parameters. If not throw exception. // Get parameters for matching mapping MethodInfo mi = typeof(SiteContext).GetMethod(procName); if (mi == null) { throw new Exception(String.Format("Stored proc mapping for {0} missing in DBContext", procName)); } ParameterInfo[] methodParams = mi.GetParameters(); // Finished getting parameters // Get parameters from stored proc int spParamCount = 0; using (StreamReader reader = new StreamReader(file)) { string line; while ((line = reader.ReadLine()) != null) { // If end of parameter section, break out if (line.ToUpper() == "BEGIN") { break; } else { if (line.Contains("@")) { spParamCount++; } } } } // Finished get parameters from stored proc if (methodParams.Count() != spParamCount) { string err = String.Format("Stored proc mapping for {0} in DBContext exists but has {1} parameter(s)" + " The stored procedure {0} has {2} parameter(s)", procName, methodParams.Count().ToString(), spParamCount.ToString()); throw new Exception(err); } else { context.Database.ExecuteSqlCommand(File.ReadAllText(file), new object[0]); } }

¡Disfrutar!

Entity Framework 4.1 Code First funciona muy bien al crear tablas y relaciones. ¿Es posible crear vistas SQL o procedimientos almacenados utilizando el enfoque de Code first? Cualquier puntero con respecto a esto será altamente apreciado. ¡Muchas gracias!


A primera vista, me gusta mucho el enfoque de Carl G, pero implica mucha interacción manual. En mi caso, siempre descarto todos los procedimientos almacenados, vistas ... y los vuelvo a crear siempre que haya un cambio en la base de datos. De esta manera estamos seguros de que todo está actualizado con la última versión.

La recreación ocurre al configurar el siguiente Inicializador:

Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>());

Entonces nuestro método de semilla será llamado cuando haya una migración lista

protected override void Seed(DeploymentLoggingContext context) { // Delete all stored procs, views foreach (var file in Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Sql//Seed"), "*.sql")) { context.Database.ExecuteSqlCommand(File.ReadAllText(file), new object[0]); } // Add Stored Procedures foreach (var file in Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Sql//StoredProcs"), "*.sql")) { context.Database.ExecuteSqlCommand(File.ReadAllText(file), new object[0]); } }

Las declaraciones SQL se almacenan en archivos * .sql para facilitar la edición. Asegúrese de que sus archivos tengan "Acción de compilación" configurada en "Contenido" y "Copiar en el directorio de salida" configurada en "Copiar siempre". Buscamos las carpetas y ejecutamos todos los scripts dentro. No olvide excluir las declaraciones "GO" en su SQL porque no pueden ejecutarse con ExecuteSqlCommand ().

Mi diseño de directorio actual es el siguiente:

Proyecto.DAL
+ Migraciones
+ Sql
++ Semilla
+++ dbo.cleanDb.sql
++ StoredProcs
+++ dbo.sp_GetSomething.sql

Ahora solo tiene que colocar procedimientos almacenados adicionales en la carpeta y todo se actualizará adecuadamente.


Admitimos procedimientos almacenados en nuestro Código de Entity Framework First Migrations. Nuestro enfoque es crear una carpeta para guardar los archivos .sql (~ / Sql / por ejemplo). Cree archivos .sql en la carpeta para crear y eliminar el procedimiento almacenado. Por ejemplo, Create_sp_DoSomething.sql y Drop_sp_DoSomething . Debido a que el SQL se ejecuta en un lote y CREATE PROCEDURE.. debe ser la primera declaración de un lote, haga que CREATE PROCEDURE... la primera declaración en el archivo. Además, no pongas GO después de la DROP... Agregue un archivo de recursos a su proyecto, si aún no tiene uno. Arrastre los archivos .sql desde el explorador de soluciones a la vista Archivos del diseñador de Recursos. Ahora cree una migración vacía ( Add-Migration SomethingMeaningful_sp_DoSomething ) y use:

namespace MyApplication.Migrations { using System; using System.Data.Entity.Migrations; public partial class SomethingMeaningful_sp_DoSomething : DbMigration { public override void Up() { this.Sql(Properties.Resources.Create_sp_DoSomething); } public override void Down() { this.Sql(Properties.Resources.Drop_sp_DoSomething); } } }

~ / Sql / Create_sp_DoSomething.sql

CREATE PROCEDURE [dbo].[sp_DoSomething] AS BEGIN TRANSACTION -- Your stored procedure here COMMIT TRANSACTION GO

~ / Sql / Drop_sp_DoSomething.sql

DROP PROCEDURE [dbo].[sp_DoSomething]


Como señaló Ladislav, DbContext en general tiende a minimizar la lógica en la base de datos, pero es posible ejecutar SQL personalizado usando context.Database.ExecuteSqlCommand() o context.Database.SqlQuery() .


El enfoque de código primero de EF espera que no haya lógica en la base de datos. Eso significa que no hay procedimientos almacenados y no hay vistas de base de datos. Debido a que el enfoque de código primero no proporciona ningún mecanismo para generar tales construcciones automáticamente para usted. ¿Cómo podría hacer eso si significa generar lógica?

Deben crearlos en el inicializador de base de datos personalizado mediante la ejecución manual de los scripts de creación. No creo que estas construcciones SQL personalizadas puedan ser manejadas por migraciones SQL.


Para ampliar la respuesta de bbodenmiller , en Entity Framework 6, la clase DbMigration tiene métodos como AlterStoredProcedure que permiten la modificación de procedimientos almacenados sin tener que descender completamente a SQL en bruto.

Este es un ejemplo de un método de migración Up() que altera un procedimiento almacenado de SQL Server existente llamado EditItem que toma tres parámetros de tipo int , nvarchar(50) y smallmoney , respectivamente:

public partial class MyCustomMigration : DbMigration { public override void Up() { this.AlterStoredProcedure("dbo.EditItem", c => new { ItemID = c.Int(), ItemName = c.String(maxLength:50), ItemCost = c.Decimal(precision: 10, scale: 4, storeType: "smallmoney") }, @" (Stored procedure body SQL goes here) " } //... }

En mi máquina, este script de migración produce el siguiente SQL:

ALTER PROCEDURE [dbo].[EditItem] @ItemID [int], @ItemName [nvarchar](50), @ItemCost [smallmoney] AS BEGIN (Stored procedure body SQL goes here) END