Linq存储过程返回XML

Pea*_*arl 7 c# xml linq stored-procedures entity-framework

我正在使用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
Run Code Online (Sandbox Code Playgroud)

LINQ实体框架:

using (DBContext db = new DBContext())
{
    var ProductList = await db.Database.ExecuteSqlCommandAsync("exec xml_test");
}
Run Code Online (Sandbox Code Playgroud)

这里的ProductList列表返回-1.

我想获取存储过程返回的xml输出.

注意:我也尝试了类似的方法:ExecuteSqlCommand,SqlQuery没有帮助.

Sal*_*ari 6

基于MSDN:

对于UPDATE,INSERT和DELETE语句,返回值是受命令影响的行数.当插入或更新的表上存在触发器时,返回值包括插入或更新操作影响的行数以及受触发器或触发器影响的行数.对于所有其他类型的语句,返回值为-1.如果发生回滚,则返回值也为-1.

因此ExecuteSqlCommand,对于像Insert,这样的查询返回一个int Update,Delete它表示单个非查询影响数.所以ExecuteSqlCommand不适合查询.

这也是一个常见问题,因为实体框架不能支持开箱即用的存储过程返回值,这是因为EF是ORM,而不是SQL替换.在Model First中检查以下链接是否存在类似问题:

使用Entity Framework从存储过程中获取数据

这与ExecuteNonQuery:

尽管使用了查询字符串,但在使用sql COUNT时,ExecuteNonQuery返回-1

解决方案:对于查询,您需要使用Database.SqlQuery<TElement>方法:

var ProductList = db.Database.SqlQuery<string>("exec xml_test").ToList();
Run Code Online (Sandbox Code Playgroud)


shA*_*A.t 5

我认为你可以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>");
}
Run Code Online (Sandbox Code Playgroud)

SET NOCOUNT ON;注意:要从存储过程中获取记录,您需要在 ;)之后添加BEGIN

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>");
}
Run Code Online (Sandbox Code Playgroud)


M. *_*cki 2

Database.ExecuteSqlCommand执行用于 CRUD 操作的命令,而不是查询。

使用Database.SqlQueryis 进行查询。它将返回给定类型的元素,但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
Run Code Online (Sandbox Code Playgroud)