usar stored procedimientos procedimiento parametros mvc mapear framework first executesqlcommand ejecutar con code almacenados almacenado agregar c# entity-framework

c# - stored - ¿Cómo llamar al procedimiento almacenado en Entity Framework 6(código primero)?



mapear stored procedure entity framework (16)

Soy muy nuevo en Entity Framework 6 y quiero implementar procedimientos almacenados en mi proyecto. Tengo un procedimiento almacenado de la siguiente manera:

ALTER PROCEDURE [dbo].[insert_department] @Name [varchar](100) AS BEGIN INSERT [dbo].[Departments]([Name]) VALUES (@Name) DECLARE @DeptId int SELECT @DeptId = [DeptId] FROM [dbo].[Departments] WHERE @@ROWCOUNT > 0 AND [DeptId] = SCOPE_IDENTITY() SELECT t0.[DeptId] FROM [dbo].[Departments] AS t0 WHERE @@ROWCOUNT > 0 AND t0.[DeptId] = @DeptId END

Department clase:

public class Department { public int DepartmentId { get; set; } public string Name { get; set; } } modelBuilder .Entity<Department>() .MapToStoredProcedures(s => s.Update(u => u.HasName("modify_department") .Parameter(b => b.Department, "department_id") .Parameter(b => b.Name, "department_name")) .Delete(d => d.HasName("delete_department") .Parameter(b => b.DepartmentId, "department_id")) .Insert(i => i.HasName("insert_department") .Parameter(b => b.Name, "department_name"))); protected void btnSave_Click(object sender, EventArgs e) { string department = txtDepartment.text.trim(); // here I want to call the stored procedure to insert values }

Mi problema es: ¿cómo puedo llamar al procedimiento almacenado y pasarle parámetros?


Ahora también puede usar una convención que creé que permite invocar procedimientos almacenados (incluidos los procedimientos almacenados que devuelven múltiples conjuntos de resultados), TVF y UDF escalares de EF.

Hasta que se publicara Entity Framework 6.1, las funciones de almacenamiento (es decir, funciones con valores de tabla y procedimientos almacenados) se podían usar en EF solo cuando se hacía la base de datos primero. Hubo algunas soluciones que permitieron invocar las funciones de la tienda en las aplicaciones de Code First, pero aún no se podían usar los TVF en las consultas de Linq, lo que era una de las mayores limitaciones. En EF 6.1, la API de mapeo se hizo pública, lo que (junto con algunos ajustes adicionales) hizo posible usar las funciones de la tienda en sus aplicaciones de Code First.

Lee mas

Presioné bastante durante las últimas dos semanas y aquí está la versión beta de la convención que permite usar funciones de almacenamiento (es decir, procedimientos almacenados, funciones de tabla de valores, etc.) en aplicaciones que utilizan el enfoque de Code First y Entity Framework 6.1.1 ( o mas nuevo). Estoy más que contento con las correcciones y las nuevas características que se incluyen en esta versión.

Leer más


Cuando EDMX cree este tiempo si selecciona el procedimiento almacenado en la opción de selección de tabla, simplemente llame a la tienda procesada usando el nombre del procedimiento ...

var num1 = 1; var num2 = 2; var result = context.proc_name(num1,num2).tolist();// list or single you get here.. using same thing you can call insert,update or delete procedured.


Descubrí que la llamada al procedimiento de procedimientos almacenados en el Código Primero no es conveniente. Prefiero usar Dapper lugar de

El siguiente código fue escrito con Entity Framework :

var clientIdParameter = new SqlParameter("@ClientId", 4); var result = context.Database .SqlQuery<ResultForCampaign>("GetResultsForCampaign @ClientId", clientIdParameter) .ToList();

El siguiente código fue escrito con Dapper :

return Database.Connection.Query<ResultForCampaign>( "GetResultsForCampaign ", new { ClientId = 4 }, commandType: CommandType.StoredProcedure);

Creo que la segunda pieza de código es más fácil de entender.


Eche un vistazo a este enlace que muestra cómo funciona la asignación de EF 6 con procedimientos almacenados para realizar una inserción, actualización y eliminación: http://msdn.microsoft.com/en-us/data/dn468673

Adición

Aquí hay un gran ejemplo para llamar a un procedimiento almacenado desde Code First:

Digamos que tiene que ejecutar un procedimiento almacenado con un solo parámetro, y que el procedimiento almacenado devuelve un conjunto de datos que coinciden con los estados de entidad, por lo que tendremos esto:

var countryIso = "AR"; //Argentina var statesFromArgentina = context.Countries.SqlQuery( "dbo.GetStatesFromCountry @p0", countryIso );

Ahora digamos que queremos ejecutar otro procedimiento almacenado con dos parámetros:

var countryIso = "AR"; //Argentina var stateIso = "RN"; //Río Negro var citiesFromRioNegro = context.States.SqlQuery( "dbo.GetCitiesFromState @p0, @p1", countryIso, stateIso );

Observe que estamos usando nombres basados ​​en índices para los parámetros. Esto se debe a que Entity Framework ajustará estos parámetros como objetos DbParameter para evitar cualquier problema de inyección de SQL.

Espero que este ejemplo ayude!


Está utilizando MapToStoredProcedures() que indica que está asignando sus entidades a procedimientos almacenados. Al hacer esto, debe dejar de lado el hecho de que hay un procedimiento almacenado y usar el context manera normal. Algo como esto ( escrito en el navegador por lo que no está probado )

using(MyContext context = new MyContext()) { Department department = new Department() { Name = txtDepartment.text.trim() }; context.Set<Department>().Add(department); }

Si lo único que intenta hacer es llamar directamente a un procedimiento almacenado, entonces use SqlQuery


Esto es lo que EF (DB primero) genera en la clase DbContext:

public ObjectResult<int> Insert_Department(string department) { var departmentParameter = new ObjectParameter("department", department); return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<int>("insert_department", departmentParameter); }


Esto me funciona al retirar datos de un procedimiento almacenado mientras se pasa un parámetro.

var param = new SqlParameter("@datetime", combinedTime); var result = _db.Database.SqlQuery<QAList>("dbo.GetQAListByDateTime @datetime", param).ToList();

_db es el dbContext


Funciona para mí en el código primero. Devuelve una lista con la propiedad coincidente del modelo de vista (StudentChapterCompletionViewModel)

var studentIdParameter = new SqlParameter { ParameterName = "studentId", Direction = ParameterDirection.Input, SqlDbType = SqlDbType.BigInt, Value = studentId }; var results = Context.Database.SqlQuery<StudentChapterCompletionViewModel>( "exec dbo.sp_StudentComplettion @studentId", studentIdParameter ).ToList();

Actualizado para el contexto

El contexto es la instancia de la clase que Hereda DbContext como a continuación.

public class ApplicationDbContext : DbContext { public DbSet<City> City { get; set; } } var Context = new ApplicationDbContext();


Lo resolví con ExecuteSqlCommand

Ponga su propio método como el mío en DbContext como sus propias instancias:

public void addmessage(<yourEntity> _msg) { var date = new SqlParameter("@date", _msg.MDate); var subject = new SqlParameter("@subject", _msg.MSubject); var body = new SqlParameter("@body", _msg.MBody); var fid = new SqlParameter("@fid", _msg.FID); this.Database.ExecuteSqlCommand("exec messageinsert @Date , @Subject , @Body , @Fid", date,subject,body,fid); }

para que pueda tener un método en su código subyacente como este:

[WebMethod] //this method is static and i use web method because i call this method from client side public static void AddMessage(string Date, string Subject, string Body, string Follower, string Department) { int resault; try { using (DBContex reposit = new DBContex()) { msge <yourEntity> Newmsg = new msge(); Newmsg.MDate = Date; Newmsg.MSubject = Subject.Trim(); Newmsg.MBody = Body.Trim(); Newmsg.FID= 5; reposit.addmessage(Newmsg); } } catch (Exception) { throw; } }

este es mi SP:

Create PROCEDURE dbo.MessageInsert @Date nchar["size"], @Subject nchar["size"], @Body nchar["size"], @Fid int AS insert into Msg (MDate,MSubject,MBody,FID) values (@Date,@Subject,@Body,@Fid) RETURN

la esperanza te ayudó


Puede llamar a un procedimiento almacenado en su clase DbContext la siguiente manera.

this.Database.SqlQuery<YourEntityType>("storedProcedureName",params);

Pero si su procedimiento almacenado devuelve múltiples conjuntos de resultados como su código de muestra, entonces puede ver este artículo útil en MSDN

Procedimientos almacenados con conjuntos de resultados múltiples


Si desea pasar parámetros de tabla al procedimiento almacenado, debe establecer la propiedad TypeName para sus parámetros de tabla.

SqlParameter codesParam = new SqlParameter(CODES_PARAM, SqlDbType.Structured); SqlParameter factoriesParam = new SqlParameter(FACTORIES_PARAM, SqlDbType.Structured); codesParam.Value = tbCodes; codesParam.TypeName = "[dbo].[MES_CodesType]"; factoriesParam.Value = tbfactories; factoriesParam.TypeName = "[dbo].[MES_FactoriesType]"; var list = _context.Database.SqlQuery<MESGoodsRemain>($"{SP_NAME} {CODES_PARAM}, {FACTORIES_PARAM}" , new SqlParameter[] { codesParam, factoriesParam } ).ToList();


Todo lo que tiene que hacer es crear un objeto que tenga los mismos nombres de propiedad que los resultados devueltos por el procedimiento almacenado. Para el siguiente procedimiento almacenado:

CREATE PROCEDURE [dbo].[GetResultsForCampaign] @ClientId int AS BEGIN SET NOCOUNT ON; SELECT AgeGroup, Gender, Payout FROM IntegrationResult WHERE ClientId = @ClientId END

crear una clase que se parece a:

public class ResultForCampaign { public string AgeGroup { get; set; } public string Gender { get; set; } public decimal Payout { get; set; } }

y luego llame al procedimiento haciendo lo siguiente:

using(var context = new DatabaseContext()) { var clientIdParameter = new SqlParameter("@ClientId", 4); var result = context.Database .SqlQuery<ResultForCampaign>("GetResultsForCampaign @ClientId", clientIdParameter) .ToList(); }

El resultado contendrá una lista de objetos ResultForCampaign . Puede llamar a SqlQuery utilizando tantos parámetros como sea necesario.


Usando su ejemplo, aquí hay dos maneras de lograr esto:

1 - Usar mapeo de procedimientos almacenados

Tenga en cuenta que este código funcionará con o sin mapeo. Si desactiva la asignación en la entidad, EF generará una declaración de inserción + selección.

protected void btnSave_Click(object sender, EventArgs e) { using (var db = DepartmentContext() ) { var department = new Department(); department.Name = txtDepartment.text.trim(); db.Departments.add(department); db.SaveChanges(); // EF will populate department.DepartmentId int departmentID = department.DepartmentId; } }

2 - Llamar directamente al procedimiento almacenado.

protected void btnSave_Click(object sender, EventArgs e) { using (var db = DepartmentContext() ) { var name = new SqlParameter("@name, txtDepartment.text.trim()); //to get this to work, you will need to change your select inside dbo.insert_department to include name in the resultset var department = db.Database.SqlQuery<Department>("dbo.insert_department @name", name).SingleOrDefault(); //alternately, you can invoke SqlQuery on the DbSet itself: //var department = db.Departments.SqlQuery("dbo.insert_department @name", name).SingleOrDefault(); int departmentID = department.DepartmentId; } }

Recomiendo usar el primer enfoque, ya que puede trabajar directamente con el objeto de departamento y no tiene que crear un grupo de objetos de Parámetro Sql.


Mindless pasajeros tiene un proyecto que permite que se devuelvan múltiples conjuntos de resultados desde un proceso almacenado utilizando el marco de entidad. Uno de sus ejemplos a continuación ...

using (testentities te = new testentities()) { //------------------------------------------------------------- // Simple stored proc //------------------------------------------------------------- var parms1 = new testone() { inparm = "abcd" }; var results1 = te.CallStoredProc<testone>(te.testoneproc, parms1); var r1 = results1.ToList<TestOneResultSet>(); }


object[] xparams = { new SqlParameter("@ParametterWithNummvalue", DBNull.Value), new SqlParameter("@In_Parameter", "Value"), new SqlParameter("@Out_Parameter", SqlDbType.Int) {Direction = ParameterDirection.Output}}; YourDbContext.Database.ExecuteSqlCommand("exec StoreProcedure_Name @ParametterWithNummvalue, @In_Parameter, @Out_Parameter", xparams); var ReturnValue = ((SqlParameter)params[2]).Value;


public IList<Models.StandardRecipeDetail> GetRequisitionDetailBySearchCriteria(Guid subGroupItemId, Guid groupItemId) { var query = this.UnitOfWork.Context.Database.SqlQuery<Models.StandardRecipeDetail>("SP_GetRequisitionDetailBySearchCriteria @SubGroupItemId,@GroupItemId", new System.Data.SqlClient.SqlParameter("@SubGroupItemId", subGroupItemId), new System.Data.SqlClient.SqlParameter("@GroupItemId", groupItemId)); return query.ToList(); }