EF6数据库首先使存储过程异步 [英] EF6 Database First making Stored Procedure Async

查看:80
本文介绍了EF6数据库首先使存储过程异步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What's the right way to run a EF6 stored procedure (database-first) in async mode?

我读到有关 ToListAsync(),但在存储过程中看不到它。

I read about ToListAsync() but I don't see that available on stored procedure.

也不确定在实际情况下是否有其他方法来调用存储过程调用返回(#1)OUT参数或(#2)项列表:

Also not sure if there is a different way to call the stored procedure when the actual call returns (#1) an OUT param or a (#2) list of items:

案例#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");
 }

感谢帮助

推荐答案

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

To map stored procedures and start using it with out writing any initial code, this is how I did it.


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

  1. create a new model with a new connection string that will generate the connection string automatically in the web.config file where the connection string is at (if you use a current connection string it may no work when you test the function for the SP on the model browser).

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

map your table and the stored procedures (you can test the stored procedures in the model browser).

创建代表每个存储过程所检索属性的类,例如,如果存储过程返回三个列A,B,C,则该类还必须将这三个列作为属性,并在要成为PK的列顶部使用[key()]

create classes that represents the attributes retrieved by each stored procedure e.g if your stored procedure returns three columns A,B,C, then the class must also have these three columns as attribute with the [key()] on top of the column that is going to be the PK

现在使用该类创建控制器创建并创建一个新的 DbContext

now create your controller with the class created and a new DbContext

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

then copy the information in the data context generated for the model and pasted in the new context that you generate when creating the controller.

当您要使用存储过程时,它们将在db.context上就绪,因为您粘贴了

when you want to use the store procedures they will be ready on the db.context because you paste their code on you new db-context that you create when the controller was crated.

注意:我希望这是在创建控制器时创建的新数据库上下文上的代码。不会混淆,但是我可以使用存储过程而无需键入任何代码,请问我是否需要示例代码或屏幕截图,创建后新的数据库上下文不会被覆盖

NOTE: I hope this is not confusing but I can use the stored procedures with out typing any code, please ask me if you need sample code or screen shots, your new db-context will not over write after you created

这是我映射的存储过程

'--------------------------------------------------------------------------
' <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()> 一起使用,并创建了自己的上下文,如下所示

SO, when I create the controller I use the model with the <KEY()> and I create my own context that will look like this

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生成的上下文中的信息复制到我的上下文中

Then I copy the info in the context generated by the EF to my context

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

因此,现在您可以使用此上下文查询

So, now you can use this context to query

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

或获取 DBSet(会议)

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

Here is a controller I have created with this technique

看我在哪里调用存储过程

Look where I call my stored procedure

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

结束命名空间

这篇关于EF6数据库首先使存储过程异步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆