这里我有blazor服务器应用程序,其中我有存储过程[dbo].[spGetAllChapter]
,它在SSMS中返回章节名称、类名和主题名称的列表。
为了调用这个存储过程[dbo].[spGetAllChapter]
,我使用了_dbContext.Database.ExecuteSqlRaw()
。
现在,问题是在调用存储过程时,它不会返回列表,而是显示-1值,但在SSMS中执行相同的存储过程时返回列表。
下面是我的存储过程
ALTER PROCEDURE [dbo].[spGetAllChapter]
AS
BEGIN
SELECT CH.ChapterId
, CH.ChapterName
, SC.ClassName
, S.SubjectName
FROM [dbo].[Chapter] AS CH
JOIN [dbo].[SchoolClass] AS SC
ON CH.SchoolClassId= SC.SchoolClassId
JOIN [dbo].[Subject] AS S
ON CH.SubjectId = S.SubjectId
END
以下是我如何调用存储过程
public eLearningDBContext _dbContext = new eLearningDBContext();
//getChapterList is -1 instead of returning list from procedure
var getChapterList = _dbContext.Database.ExecuteSqlRaw($"EXEC dbo.spGetAllChapter");
ExecuteSqlRaw的文档说函数:
Executes the given SQL against the database and returns the number of rows affected.
请注意,它不返回数据,而是返回受影响的行数。也许你正在寻找的是FromSqlRaw
或者,你不需要一个存储过程来完成你想要的;您可以简单地在常规EF查询中投影所需的列,例如:
_dbContext.Chapters.Select(ch => new
{
ChapterId = ch.ChapterId,
ChapterName = ch.ChapterName,
ClassName = ch.SchoolClass.ClassName,
SubjectName = ch.Subject.SubjectName
}).ToList()
这将为您提供一个包含所需字段的匿名对象列表,但您也可以创建一个命名类型(如ChapterAbstract
或其他类型(并投影到该类型。
如果上下文是先创建DB的,则可以通过向导更新DataModel以包含存储过程和函数。然后您可以直接从上下文调用SP
_dbcontext.spGetAllChapter((;
我知道如何通过使这个助手类来解决
public static class SQLHelper
{
public static List<T> RawSqlQuery<T>(string query, Func<DbDataReader, T> function)
{
using (var context = new eLearningDBContext())
{
using (var command = context.Database.GetDbConnection().CreateCommand())
{
command.CommandText = query;
command.CommandType = CommandType.Text;
context.Database.OpenConnection();
using (var result = command.ExecuteReader())
{
var entities = new List<T>();
while (result.Read())
{
entities.Add(function(result));
}
return entities;
}
}
}
}
}
var list = SQLHelper.RawSqlQuery($"EXEC dbo.spGetAllChapter",
x => new ChapterVM {
ChapterId = (int)x[0],
ChapterName = (string)x[1],
ClassName = (string)x[2],
SubjectName = (string)x[3]
}).ToList();