我对实体框架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();

其他回答

我用ExecuteSqlCommand解决了这个问题

把你自己的方法放在DbContext中作为你自己的实例:

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);
}

所以你可以在你的后台代码中有一个这样的方法:

[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)
{
    try
    {
        using (DBContext reposit = new DBContext())
        {
            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;
    }
}

这是我的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

希望这对你有帮助。

在MYsql中创建Procedure。

delimiter //
create procedure SP_Dasboarddata(fromdate date, todate date)
begin
select count(Id) as count,date,status,sum(amount) as amount from 
details
where (Emidate between fromdate and todate)
group by date ,status;
END;
//

创建包含存储过程返回结果集值的类

[Table("SP_reslutclass")]
public  class SP_reslutclass
{
    [Key]
    public int emicount { get; set; }
    public DateTime Emidate { get; set; }
    public int ? Emistatus { get; set; }
    public int emiamount { get; set; }

}

在Dbcontext中添加Class

  public  class ABCDbContext:DbContext
{
    public ABCDbContext(DbContextOptions<ABCDbContext> options)
       : base(options)
    {

    }

 public DbSet<SP_reslutclass> SP_reslutclass { get; set; }
}

在存储库中调用实体

   var counts = _Dbcontext.SP_reslutclass.FromSql("call SP_Dasboarddata 
                    ('2019-12-03','2019-12-31')").ToList();

.NET Core 5.0没有FromSql,而是有frommsqlraw

下面这些都对我有用。这里的帐户类是c#中的实体,具有与数据库中完全相同的表和列名。

App配置类如下所示

class AppConfiguration
{
    public AppConfiguration()
    {
        var configBuilder = new ConfigurationBuilder();
        var path = Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json");
        configBuilder.AddJsonFile(path, false);
        var root = configBuilder.Build();
        var appSetting = root.GetSection("ConnectionStrings:DefaultConnection");
        sqlConnectionString = appSetting.Value;
    }

    public string sqlConnectionString { get; set; }
}

DbContext类:

public class DatabaseContext : DbContext
{
    public class OptionsBuild
    {
        public OptionsBuild()
        {
            setting = new AppConfiguration();
            opsBuilder = new DbContextOptionsBuilder<DatabaseContext>();
            opsBuilder.UseSqlServer(setting.sqlConnectionString);
            dbOptions = opsBuilder.Options;
        }

        public DbContextOptionsBuilder<DatabaseContext> opsBuilder { get; set; }
        public DbContextOptions<DatabaseContext> dbOptions { get; set; }

        private AppConfiguration setting { get; set; }
    }

    public static OptionsBuild ops = new OptionsBuild();

    public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
    {
        //disable initializer
        //  Database.SetInitializer<DatabaseContext>(null);
    }

    public DbSet<Account> Account { get; set; }
}

这段代码应该在你的数据访问层:

List<Account> accounts = new List<Account>();
var context = new DatabaseContext(DatabaseContext.ops.dbOptions);
accounts = await context.Account.ToListAsync();   //direct select from a table

var param = new SqlParameter("@FirstName", "Bill");
accounts = await context.Account.FromSqlRaw<Account>("exec Proc_Account_Select", 
param).ToListAsync();            //procedure call with parameter
        
accounts = context.Account.FromSqlRaw("SELECT * FROM dbo.Account").ToList();  //raw query

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

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

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

我发现以代码优先的方式调用存储过程并不方便。

我更喜欢用Dapper代替。

下面的代码是用实体框架编写的:

var clientIdParameter = new SqlParameter("@ClientId", 4);

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

以下代码是用Dapper编写的:

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

我认为第二段代码更容易理解。