将存储过程从 LINQ 迁移到 SQL 到 Entity Framework 6

Migrating stored procedure from LINQ to SQL to Entity Framework 6

我已经将我的项目从 Linq-to-SQL 迁移到 Entity Framework 6. 在解决了这么多问题之后,我终于遇到了一个我不知道该怎么办的问题。转换后,大约三分之一的单元测试失败,因为存储过程 returning 标量值 just work different way.

在 Linq-to-SQL 中,存储过程 return returned 值。在 EF 中,它们 return 受影响的行数。有一些变通方法需要更改存储过程(通常从 RETURN @retvalueSELECT @retvalue)。但这需要T-SQL的变化。该项目仍然包含一些 ASP.NET 过去的遗留代码,例如 aspnet_Membership_CreateUser 等等。这意味着我无法更改这些存储过程,因为 ASP.NET ADO.NET 成员资格提供程序部分使用了这些存储过程,部分 Linq-to-SQL 代码使用了这些存储过程。我考虑的解决方案是为这些遗留代码制作 T-SQL 包装器。

我想保持存储过程不变的另一个原因是,如果升级到 EF 不成功,可能会恢复到之前的提交。不想来回更改数据库。不过这个理由并没有那么强烈,只是我懒惰而已。

我知道会员提供程序是老式的,但我不能在一次提交中重写整个应用程序,我需要保持它的稳定性。

完成迁移的最佳方法是从 EF 调用存储过程,如 Linq-to-SQL,但我没有找到方法。 EF 在这方面让我很失望。经过多年的发展,EF 怎么可能不支持 returning 存储过程中的标量值?

你会如何解决这个问题?

嗨 Qub1n,

    // Create the gender parameter var param1 = new SqlParameter {
    ParameterName = "@userId",
    Value = _userId };

    // Create the return code var returnValue = new SqlParameter {
    ParameterName = "@ReturnCode",
    SqlDbType = System.Data.SqlDbType.Int,
    Direction = System.Data.ParameterDirection.Output };


    // Gender is an int column in the database.
    _context
    .Database
    .ExecuteSqlCommand("exec @ReturnCode = GetGenderOfUser     @userId", 
    param1,    returnValue);

    return (int)returnValue.Value;

这对我有用。我的存储过程是这样的:

CREATE PROCEDURE [dbo].[GetGenderOfUser] 
    -- Add the parameters for the stored procedure here
    @userId uniqueidentifier 
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    declare @retval int
    -- Insert statements for procedure here
    set @retval = (select top(1) Gender from Users where Guid = @userId)

    return @retval
END

如果可行,请告诉我!

最后我得到了包装器,它保留了数据库的原始功能(对于 ASP.NET MembershipProvider)并为 EntityFramework:

创建了存储过程的版本
CREATE PROCEDURE [dbo].[aspnet_UsersInRoles_AddUsersToRolesEF]
    @ApplicationName  nvarchar(256),
    @UserNames        nvarchar(4000),
    @RoleNames        nvarchar(4000),
    @CurrentTimeUtc   datetime
AS
BEGIN
    DECLARE @return_value int

EXEC    @return_value = [dbo].[aspnet_UsersInRoles_AddUsersToRoles]
        @ApplicationName,
        @UserNames,
        @RoleNames,
        @CurrentTimeUtc

SELECT  @return_value
END

GO

现在我可以使用编译器检查存储过程中参数的数量和类型。