MVC 5,EF 6和“从数据库代码优先”存储过程

7
在搜索答案时,即使使用引号括起来的关键词“Code First from Database”,我发现并没有涉及到具体术语的答案,因此我只想问一个关于“仅从数据库生成代码”的问题。
在使用Entity Framework 6的ASP.NET MVC 5 Web应用程序中,我希望能够使用“ADO.NET Entity Data Model”向已存在的存储过程进行映射。
为什么我要问这个问题以及我希望实现什么目标?
这个特定的存储过程是一个参数化查询,在View中用户会通过表单提交一个日期范围,并在表格中接收该查询的结果。在SQL Server端,这很容易:声明两个日期并获取您的查询结果。
我希望用户可以从View中“简单地”选择一个日期范围并立即看到由存储过程查询提供的结果。
以下是显示我尝试使用向导映射存储过程的屏幕截图。
1. 指定数据库上下文名称

Specify name of database context

2. 指定 "从数据库生成代码优先"

Specify "Code First From Database"

3. 选择数据库连接

Choose Database Connection

4.没有存储过程可用
我还注意到导入存储过程的选项被禁用了。

No stored procedures are available

4个回答

4

我正在尝试这种方法,但是遇到了这个错误:“对象类型System.DateTime[]和已知托管提供程序本机类型之间不存在映射。” DateTime []参数 = new DateTime [2] {d1,d2}; var query = db.Database.SqlQuery < PerfOdomoeterDate >(“GetCreditSumByDateRange”,parameters).ToList(); 还在继续努力。 - user4864716
我将您的答案标记为正确答案。我犯了一些学习曲线上的错误,但最有益的是“如何在Entity Framework 6(Code-First)中调用存储过程?”不久我会在我的答案中添加一个完整的逐步过程。 - user4864716

3

我的问题的直接答案是,我无法欺骗向导导入存储过程。

相反,这是我需要做的:

  1. 确保我的存储过程有一个类型为int的ID列
SELECT DISTINCT ID = cast(ROW_NUMBER() OVER (
              ORDER BY z.Campus,
                  z.StudentName,
                  z.StudentID
              ) AS INT),
      -- ....
在Models文件夹中,手动创建我的类和属性定义。
public class PerfOdomoeterDate
{        
  public int ID { get; set; }
  public string Campus { get; set; }
  public string StudentName { get; set; }
  public int StudentID { get; set; }
  public DateTime StartDate { get; set; }
  public DateTime EndDate { get; set; }
  public double Credits { get; set; }
}
  1. 在数据库上下文文件中添加:

public virtual DbSet<PerfOdomoeterDate> PerfOdomoeterDates { get; set; }

  1. 不要在"OnModelCreating"函数中添加任何内容。

  2. 右键单击控制器文件夹,选择新的模板项:"使用Entity Framework的MVC 5控制器"。

  3. 所示的Index操作是一个“hello world”样本,以确保与存储过程建立基本联系。我肯定会使用视图模型、参数等自定义它。但这应该清楚地显示如何让你的代码工作。

private PerformanceContext db = new PerformanceContext();        

[HttpGet]
public ActionResult Index()
{   
  // These will be filled by form submission
  DateTime d1 = Convert.ToDateTime("12/1/2014");
  DateTime d2 = Convert.ToDateTime("5/1/2015");

  // supply parameter values required by the stored procedure
  object[] parameters = {
      new SqlParameter("@date1",SqlDbType.DateTime) {Value=d1},
      new SqlParameter("@date2",SqlDbType.DateTime) {Value=d2}
                   };

  // populate the list by calling the stored procedure and supplying parameters
  IEnumerable<PerfOdomoeterDate> query = 
      db.Database.SqlQuery<PerfOdomoeterDate>("PerfOdomoeterDate @date1, @date2", 
          parameters).ToList();            

  return View(query);
}
重新构建并查看索引。不应该有编译或运行时错误。视图应显示所需的数据。

感谢分享你的发现! - Nick Acosta

2

权限。(确保数据库用户对存储过程具有权限)


我已经验证了权限并重新确认了它们。对我来说,这不是问题。 - user4864716

1
我不认为您目前可以通过向导完成此操作,从存储过程生成是一个相对较新的功能。
要将映射到代码中的存储过程,您需要执行以下操作。
modelBuilder 
  .Entity<Blog>() 
  .MapToStoredProcedures();

完整的细节在此帖子中

https://msdn.microsoft.com/en-us/data/dn468673.aspx


在最近的一个项目中,我使用相同的向导导入了一些存储过程,这可能是权限问题。 - Tarun Pothulapati
@TarunPothulapati - 你确定你没有使用数据库优先向导吗?我可以通过数据库优先方式导入存储过程,但是不能通过代码优先方式导入,我认为这还不被支持。 - Diskdrive

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接