3

在异步模式下运行 EF6 存储过程(数据库优先)的正确方法是什么?

我读过ToListAsync()但我没有看到存储过程中可用的。

也不确定当实际调用返回 (#1) OUT 参数或 (#2) 项目列表时是否有不同的方法来调用存储过程:

情况1

 using (DBContext db = new DBContext())
 {
     ObjectParameter result = new ObjectParameter("Result", 
                                  typeof(global::System.Boolean));

     db.Login("email@email.com", "password", result);
 }

案例#2

 using (DBContext db = new DBContext())
 {
     var result = db.Contact_GetList("New York");
 }

谢谢您的帮助

4

2 回答 2

3

根据此工作项,您需要使用SqlQueryAsync. 随意在 EF Codeplex 网站上对工作项目进行投票。

于 2013-11-11T21:48:16.160 回答
1

为了映射存储过程并在不编写任何初始代码的情况下开始使用它,我就是这样做的。

  1. 使用新的连接字符串创建一个新模型,该模型将在连接字符串web.config所在的文件中自动生成连接字符串(如果您使用当前的连接字符串,当您在模型浏览器上测试 SP 的功能时,它可能不起作用) .

  2. 映射您的表和存储过程(您可以在模型浏览器中测试存储过程)。

  3. 创建表示每个存储过程检索到的属性的类,例如,如果您的存储过程返回三列 A、B、C,则该类还必须将这三列作为属性,其中 [key()] 在列的顶部将成为PK

  4. 现在使用创建的类和一个新的类创建您的控制器DbContext

  5. 然后复制为模型生成的数据上下文中的信息,并粘贴到您在创建控制器时生成的新上下文中。

  6. 当您想使用存储过程时,它们将在 db.context 上准备就绪,因为您将它们的代码粘贴到您在创建控制器时创建的新 db-context 上。

注意:我希望这不会造成混淆,但我可以在不输入任何代码的情况下使用存储过程,如果您需要示例代码或屏幕截图,请询问我,您的新 db-context 在创建后不会覆盖

这是我映射的存储过程

'--------------------------------------------------------------------------
' <auto-generated>
'     This code was generated from a template.
'
'     Manual changes to this file may cause unexpected behavior in your application.
'     Manual changes to this file will be overwritten if the code is regenerated.
' </auto-generated>
'-----------------------------------------------------------------------

Imports System
Imports System.Collections.Generic

Partial Public Class phone_CurrentConferences_Result
    Public Property AppointmentID As Integer
    Public Property AppTitle As String
    Public Property DateTime As Nullable(Of Date)
    Public Property [Date] As String
    Public Property Time As String
    Public Property Company As String
    Public Property Contact As String
    Public Property Phone As String
    Public Property Office As String
    Public Property Lead_Director As String
    Public Property TBD As Nullable(Of Boolean)
    Public Property conference As String
End Class

这是具有主键的同一模型

Imports System
Imports System.Collections.Generic
Imports System.ComponentModel.DataAnnotations

Public Class Conferences
    [Key]
    Public Property AppointmentID As Integer
    Public Property AppTitle As String
    Public Property DateTime As Nullable(Of Date)
    Public Property [Date] As String
    Public Property Time As String
    Public Property Company As String
    Public Property Contact As String
    Public Property Phone As String
    Public Property Office As String
    Public Property Lead_Director As String
    Public Property TBD As Nullable(Of Boolean)
    Public Property conference As String
End Class

这是 EF 生成的上下文

'--------------------------------------------------------------------------
' <auto-generated>
'     This code was generated from a template.
'
'     Manual changes to this file may cause unexpected behavior in your application.
'     Manual changes to this file will be overwritten if the code is regenerated.
' </auto-generated>
'--------------------------------------------------------------------------

Imports System
Imports System.Data.Entity
Imports System.Data.Entity.Infrastructure
Imports System.Data.Entity.Core.Objects
Imports System.Linq

Partial Public Class DayMasterEntities
    Inherits DbContext

    Public Sub New()
        MyBase.New("name=DayMasterEntities")
    End Sub

    Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
        Throw New UnintentionalCodeFirstException()
    End Sub

    Public Overridable Function phone_CurrentConferences(number As String, [date] As Nullable(Of Date)) As ObjectResult(Of phone_CurrentConferences_Result)
        Dim numberParameter As ObjectParameter = If(number IsNot Nothing, New ObjectParameter("number", number), New ObjectParameter("number", GetType(String)))

        Dim dateParameter As ObjectParameter = If([date].HasValue, New ObjectParameter("date", [date]), New ObjectParameter("date", GetType(Date)))

        Return DirectCast(Me, IObjectContextAdapter).ObjectContext.ExecuteFunction(Of phone_CurrentConferences_Result)("phone_CurrentConferences", numberParameter, dateParameter)
    End Function

End Class

所以,当我创建控制器时,我使用模型<KEY()>和我创建自己的上下文,看起来像这样

Imports System.Data.Entity
Imports System.Data.Entity.Infrastructure
Imports System.Data.Entity.Core.Objects

Namespace Models

    Public Class DayMasterContext
        Inherits DbContext

        ' You can add custom code to this file. Changes will not be overwritten.
        ' 
        ' If you want Entity Framework to drop and regenerate your database
        ' automatically whenever you change your model schema, please use data migrations.
        ' For more information refer to the documentation:
        ' http://msdn.microsoft.com/en-us/data/jj591621.aspx

        Public Sub New()
            MyBase.New("name=DayMasterEntities")
        End Sub

        Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
            Throw New UnintentionalCodeFirstException()
        End Sub

        Public Property Conferences As System.Data.Entity.DbSet(Of Conferences)
    End Class
End Namespace

然后我将 EF 生成的上下文中的信息复制到我的上下文中

Imports System.Data.Entity
Imports System.Data.Entity.Infrastructure
Imports System.Data.Entity.Core.Objects

Namespace Models

    Public Class DayMasterContext
        Inherits DbContext

        ' You can add custom code to this file. Changes will not be overwritten.
        ' 
        ' If you want Entity Framework to drop and regenerate your database
        ' automatically whenever you change your model schema, please use data migrations.
        ' For more information refer to the documentation:
        ' http://msdn.microsoft.com/en-us/data/jj591621.aspx

        Public Sub New()
            MyBase.New("name=DayMasterEntities")
        End Sub

        Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
            Throw New UnintentionalCodeFirstException()
        End Sub

        Public Overridable Function phone_CurrentConferences(number As String, [date] As Nullable(Of Date)) As ObjectResult(Of phone_CurrentConferences_Result)
            Dim numberParameter As ObjectParameter = If(number IsNot Nothing, New ObjectParameter("number", number), New ObjectParameter("number", GetType(String)))

            Dim dateParameter As ObjectParameter = If([date].HasValue, New ObjectParameter("date", [date]), New ObjectParameter("date", GetType(Date)))

            Return DirectCast(Me, IObjectContextAdapter).ObjectContext.ExecuteFunction(Of phone_CurrentConferences_Result)("phone_CurrentConferences", numberParameter, dateParameter)
        End Function

        Public Property Conferences As System.Data.Entity.DbSet(Of Conferences)
    End Class
End Namespace

所以,现在你可以使用这个上下文来查询

entConferences(number As String, [date] As Nullable(Of Date)) As ObjectResult(Of phone_CurrentConferences_Result) 

或得到一个DBSet(of conferences)

这是我用这种技术创建的控制器

看看我在哪里调用我的存储过程

Dim conferences = db.phone_CurrentConferences(phoneNumber, currentDate)

Imports System.Data
Imports System.Data.Entity
Imports System.Data.Entity.Infrastructure
Imports System.Linq
Imports System.Net
Imports System.Net.Http
Imports System.Web.Http
Imports System.Web.Http.Description
Imports BIWEBAPI
Imports BIWEBAPI.Models

Namespace Controllers.DayMasterControllers
    Public Class ConferencesController
        Inherits System.Web.Http.ApiController

        Private db As New DayMasterContext

        ' GET: api/Conferences
        Function GetConferences() As IQueryable(Of Conferences)
            Return db.Conferences
        End Function

        ' GET: api/Conferences/3053742500 
        ''' <summary>
        ''' Use to get the current conferences  selected by date
        ''' </summary>
        ''' <param name="id">phone number and date separated by coma ",""</param>
        ''' <returns>conferences by date</returns>
        ''' <remarks></remarks>
        <ResponseType(GetType(Conferences))>
        Function GetConferences(ByVal id As String) As List(Of Conferences)
            Dim conferencelist = New List(Of Conferences)
            Dim dateAndPhoneNumber = Split(id, ",")
            Dim currentDate = ""
            Dim phoneNumber = dateAndPhoneNumber(0)

            If dateAndPhoneNumber.Length > 1 Then
                currentDate = DateTime.Parse(dateAndPhoneNumber(1))
            Else : currentDate = DateTime.Today
            End If

            Dim conferences = db.phone_CurrentConferences(phoneNumber, currentDate)

            For Each conferenceInQuery As Object In conferences
                Dim conference = New Conferences()
                conference.AppointmentID = conferenceInQuery.AppointmentID
                conference.AppTitle = conferenceInQuery.AppTitle
                conference.DateTime = conferenceInQuery.DateTime
                conference.[Date] = conferenceInQuery.[Date]
                conference.Time = conferenceInQuery.Time
                conference.Company = conferenceInQuery.Company
                conference.Contact = conferenceInQuery.Contact
                conference.Phone = conferenceInQuery.Phone
                conference.Office = conferenceInQuery.Office
                conference.Lead_Director = conferenceInQuery.Lead_Director
                conference.TBD = conferenceInQuery.TBD
                conference.conference = conferenceInQuery.conference

                conferencelist.Add(conference)
            Next

            Return conferencelist
        End Function

        ' PUT: api/Conferences/5
        <ResponseType(GetType(Void))>
        Function PutConferences(ByVal id As Integer, ByVal conferences As Conferences) As IHttpActionResult
            If Not ModelState.IsValid Then
                Return BadRequest(ModelState)
            End If

            If Not id = conferences.AppointmentID Then
                 Return BadRequest()
            End If

            db.Entry(conferences).State = EntityState.Modified

            Try
                db.SaveChanges()
            Catch ex As DbUpdateConcurrencyException
                If Not (ConferencesExists(id)) Then
                    Return NotFound()
                Else
                    Throw
                End If
            End Try

            Return StatusCode(HttpStatusCode.NoContent)
       End Function

       ' POST: api/Conferences
       <ResponseType(GetType(Conferences))>
       Function PostConferences(ByVal conferences As Conferences) As IHttpActionResult
           If Not ModelState.IsValid Then
               Return BadRequest(ModelState)
           End If

           db.Conferences.Add(conferences)
           db.SaveChanges()

           Return CreatedAtRoute("DefaultApi", New With {.id = conferences.AppointmentID}, conferences)
       End Function

       ' DELETE: api/Conferences/5
       <ResponseType(GetType(Conferences))>
       Function DeleteConferences(ByVal id As Integer) As IHttpActionResult
           Dim conferences As Conferences = db.Conferences.Find(id)

           If IsNothing(conferences) Then
               Return NotFound()
           End If

           db.Conferences.Remove(conferences)
           db.SaveChanges()

           Return Ok(conferences)
       End Function

       Protected Overrides Sub Dispose(ByVal disposing As Boolean)
           If (disposing) Then
               db.Dispose()
           End If

           MyBase.Dispose(disposing)
       End Sub

       Private Function ConferencesExists(ByVal id As Integer) As Boolean
           Return db.Conferences.Count(Function(e) e.AppointmentID = id) > 0
       End Function
   End Class

结束命名空间

于 2014-12-09T14:53:13.710 回答