我对实体框架6非常陌生,我想在我的项目中实现存储过程。我有一个存储过程如下:

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

系类:

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
}

我的问题是:如何调用存储过程并将参数传递给它?


当前回答

你可以将参数传递给sp_GetById并在ToList()或FirstOrDefault()中获取结果;

var param  = new SqlParameter("@id", 106);
var result = dbContext
               .Database
               .SqlQuery<Category>("dbo.sp_GetById @id", param)
               .FirstOrDefault();

其他回答

您可以在DbContext类中调用存储过程,如下所示。

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

但是如果您的存储过程返回多个结果集作为示例代码,那么您可以在MSDN上看到这篇有用的文章

具有多个结果集的存储过程

看一下这个链接,它展示了如何将EF 6与存储过程映射为插入、更新和删除:http://msdn.microsoft.com/en-us/data/dn468673

除了

下面是一个从Code First调用存储过程的好例子:

假设你必须执行一个带有单个参数的存储过程,并且该存储过程返回一组与实体状态匹配的数据,因此我们将有:

var countryIso = "AR"; //Argentina

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

现在假设我们想要执行另一个带有两个参数的存储过程:

var countryIso = "AR"; //Argentina
var stateIso = "RN"; //Río Negro

var citiesFromRioNegro = context.States.SqlQuery(
                            "dbo.GetCitiesFromState @p0, @p1", countryIso, stateIso
                          );

注意,我们对参数使用基于索引的命名。这是因为实体框架将这些参数包装为DbParameter对象,以避免任何SQL注入问题。

希望这个例子能有所帮助!

首先使用MySql和实体框架代码

public class Vw_EMIcount
{
    public int EmiCount { get; set; }
    public string Satus { get; set; }
}

var result = context.Database.SqlQuery<Vw_EMIcount>("call EMIStatus('2018-3-01' ,'2019-05-30')").ToList();

您正在使用MapToStoredProcedures(),这表明您正在将实体映射到存储过程,在执行此操作时,您需要放弃存在存储过程的事实,并正常使用上下文。 像这样(写入浏览器,所以没有测试)

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

如果你真正想做的只是直接调用存储过程,那么使用SqlQuery

现在还可以使用我创建的约定,该约定允许从EF本机调用存储过程(包括返回多个结果集的存储过程)、tvf和标量udf。

在实体框架6.1发布之前,存储函数(即表值函数和存储过程)只能在数据库优先的情况下在EF中使用。有一些变通办法可以在Code First应用中调用存储函数,但你仍然不能在Linq查询中使用tvf,这是最大的限制之一。在EF 6.1中,映射API是公开的(以及一些额外的调整),这使得在Code First应用中使用存储函数成为可能。

阅读更多

在过去的两周里,我一直在努力推广,现在终于有了这个约定的beta版本,它允许在使用代码优先方法和实体框架6.1.1(或更新版本)的应用程序中使用存储函数(即存储过程、表值函数等)。我对这个版本中包含的修复和新功能非常满意。

阅读更多。