我正在使用Entity Framework代码优先方法。我想从DbContext
类调用存储过程并获取XML输出。
存储过程(SQL Server):
CREATE PROCEDURE xml_test
AS
BEGIN
DECLARE @xml1 xml
SET @xml1 = (SELECT * from Product FOR XML RAW)
SELECT @xml1 AS my_xml
END
LINQ实体框架:
using (DBContext db = new DBContext())
{
var ProductList = await db.Database.ExecuteSqlCommandAsync("exec xml_test");
}
此处ProductList
列表返回-1。
我想获取存储过程返回的xml输出。
注意:我也尝试过这样的方法: ExecuteSqlCommand,SqlQuery ,没有任何帮助。
答案 0 :(得分:6)
基于MSDN:
对于UPDATE,INSERT和DELETE语句,返回值是受命令影响的行数。当插入或更新的表上存在触发器时,返回值包括插入或更新操作影响的行数以及受触发器或触发器影响的行数。对于所有其他类型的语句,返回值为-1。如果发生回滚,则返回值也为-1。
因此,ExecuteSqlCommand
会为Insert
,Update
,Delete
之类的查询返回一个int,这意味着单个行影响的数量非查询。所以ExecuteSqlCommand
不适合查询。
这也是一个常见问题,因为实体框架不能支持开箱即用的存储过程返回值,这是因为EF是ORM,而不是SQL替代品。请检查以下链接,了解模型优先:
中的类似问题Getting data from stored procedure with Entity Framework
这与ExecuteNonQuery
:
ExecuteNonQuery returning -1 when using sql COUNT despite the query string
解决方案:
对于查询,您需要使用Database.SqlQuery<TElement>
方法:
var ProductList = db.Database.SqlQuery<string>("exec xml_test").ToList();
答案 1 :(得分:4)
我认为你可以像这样使用SQLQuery
:
using (var dbcontext = new DBContext())
{
//Reading stored procedure results as List<string>
var r = dbcontext.Database.SqlQuery<string>("EXEC xml_test").ToList(); //Note: EXEC is optional
//Joining strings to one string that causes in resulting long strings
var xmlString = string.Join("", r);
//Now you can load your string to a XmlDocument
var xml = new XmlDocument();
//Note: You need to add a root element to your result
xml.LoadXml($"<root>{xmlString}</root>");
}
注意:要从存储过程中获取记录,您需要在
SET NOCOUNT ON;
;)之后添加BEGIN
。
CREATE PROCEDURE [dbo].[xml_test]
AS
BEGIN
SET NOCOUNT ON;
SELECT * from dbo.AspNetUsers FOR XML RAW;
END
答案 2 :(得分:2)
Database.ExecuteSqlCommand
执行用于CRUD操作的命令,而不是查询。
使用Database.SqlQuery
用于查询。它将返回给定类型的元素,但xml
不是原始类型,这可能是LINQ无法工作的原因。在存储过程中尝试cast
xml到nvarchar(max)
这将是字符串类型。
。因此,您的存储过程应如下所示:
CREATE PROCEDURE xml_test
AS
BEGIN
DECLARE @xml1 xml
SET @xml1 = (SELECT * from Product FOR XML RAW)
SELECT CAST(@xml1 as nvarchar(max))
END
答案 3 :(得分:2)
正如shA.t&#34; FOR XML&#34;可以使用。但是,使用时要注意的一件事是截断字符串/ XML(通过EF调用函数后返回)大约2k个字符,为了处理这种情况,你可以查看this。此外,如果代码设计允许,您甚至可以使用Ouptput parameters with Enitity Framework。