我有一个存储过程,它会返回0
或1
,具体取决于我的数据库中是否存在指定的电子邮件地址:
CREATE PROCEDURE [DatabaseSchema].[EmailAddressIsDuplicate] (@emailAddress nvarchar(255))
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS(
SELECT *
FROM [DatabaseSchema].[EmailUpdatesRegistrant]
WHERE EmailAddress = @emailAddress
)
RETURN 1
ELSE
RETURN 0
RETURN 0
END
GO
我正在尝试从Entity Framework 6数据库上下文中获取此存储过程的结果:
using (DatabaseContext dbContext = new DatabaseContext())
{
ObjectParameter param = new ObjectParameter("emailAddress", typeof(bool));
var result = dbContext.EmailAddressIsDuplicate(emailAddress);
}
我遇到了很多错误。
错误#1:使用上面的代码,var result
始终设置为-1。
错误#2:我尝试导航到Edit Function Import
并将Returns a Collection Of
设置为Boolean
标量值。这会引发以下错误:
商店数据提供程序返回的数据读取器没有足够的列用于请求的查询。
错误#3:我回去并将Edit Function Import
返回值设置为None
。然后我尝试了以下代码:
using (DatabaseContext dbContext = new DatabaseContext())
{
var p = new SqlParameter("@emailAddress", emailAddress);
var result = dbContext.Database.SqlQuery<bool>("DatabaseSchema.EmailAddressIsDuplicate", p);
}
没有立即出现错误,但我不知道我是否可以从var result
派生有用的数据。尝试将result
强制转换为bool
会引发以下错误:
无法将类型'System.Data.Entity.Infrastructure.DbRawSqlQuery'转换为'bool'
有关如何查看此存储过程结果的任何想法(0
或1
)?
答案 0 :(得分:1)
您可以尝试在存储过程签名中添加输出参数(@result
):
CREATE PROCEDURE [DatabaseSchema].[EmailAddressIsDuplicate]
(@emailAddress nvarchar(255), @result bit out)
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS(SELECT *
FROM [DatabaseSchema].[EmailUpdatesRegistrant]
WHERE EmailAddress = @emailAddress)
SET @result = 1
ELSE
SET @result = 0
RETURN @result
END
GO
(您必须相应地重新定义您的EF模型函数定义)
using (DatabaseContext dbContext = new DatabaseContext())
{
ObjectParameter isDuplicate = new ObjectParameter("isDuplicate", typeof(bool));
var result = dbContext.EmailAddressIsDuplicate(emailAddress, isDuplicate);
bool emailIsDuplicate = (bool)isDuplicate.Value;.
}
如果要使用out参数直接调用存储过程,可以遵循以下建议: Database.SqlQuery calling stored procedure that has multiple output parameters
答案 1 :(得分:1)
原因 - EF的模板构建器(包括v6)错误地将SP设置为返回包含行计数而不是返回值的INT,因为它错误地调用了错误的ObjectContext.ExecuteFunction(找到在模板生成的类YourDatabaseEntities中,它是DBContext的子项。
为什么错误的ExecuteFunction? - 结果集错误地表示更改行的行数而不是返回值或输出参数,因为它调用了丢弃结果的不同ExecuteFunction。 ObjectContext.ExecuteFunction的flyover intellisense提示说&#34;执行存储过程.... 丢弃从该函数返回的任何结果;并返回受执行影响的行数&#34;而不是通常&#34;执行存储过程....带有指定参数的 &#34;。
为什么-1:我认为SET NOCOUNT ON导致SP没有返回计数结果,并且Microsoft的ExecuteFunction将其作为错误代码返回。
SP FIXES - 1)您必须注释掉SET NOCOUNT ON。 2)您必须更改存储过程以将SELECT命令作为最后一个语句而不是RETURN命令。
SOLUTION FIX - 1)修复SP后,从Function Imports文件夹和Data Store的SP文件夹中删除SP。 2)使用数据库中的&#34;更新模型将SP重新加载到EDMX中。 3)重建EDMX所在的所有数据项目。 4)退出Visual Studio并返回。 5)重建整体解决方案。
请参阅:Entity Framework (Database first) has incorrect return result from stored procedure
答案 2 :(得分:0)
使用参数将C#中的存储过程实现为一个值。
资源:https://msdn.microsoft.com/en-us/library/yy6y35y8(v=vs.110).aspx
这样,值可以存储到ExecuteReader
的变量中。
将值添加到模型,类似于向属性添加值。可以从ActionResult调用存储过程。虽然这可能需要将存储过程添加到单独的层,但这只是运行存储过程并在之后将值添加到模型中。
答案 3 :(得分:-1)
试试这个
CREATE PROCEDURE [DatabaseSchema].[EmailAddressIsDuplicate] (@emailAddress nvarchar(255))
AS
BEGIN
SELECT *
FROM [DatabaseSchema].[EmailUpdatesRegistrant]
WHERE EmailAddress = @emailAddress
SELECT @@ROWCOUNT
END
GO
using (DatabaseContext dbContext = new DatabaseContext())
{
var result = dbContext.Database.SqlQuery<int32>("exec DatabaseSchema.EmailAddressIsDuplicate {0}", emailAddress).FirstOrDefault();
}
返回值中的任何其他0表示匹配,数字表示匹配数