2016-12-22 3 views
7

Я использую метод Entity Framework с кодовым подходом. Я хочу вызвать хранимую процедуру из класса DbContext и получить XML-выход.Linq хранимая процедура для возврата 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 Entity Framework:

using (DBContext db = new DBContext()) 
{ 
    var ProductList = await db.Database.ExecuteSqlCommandAsync("exec xml_test"); 
} 

Здесь ProductList список возвращается -1.

Я хочу получить выход xml, который возвращается хранимой процедурой.

Примечание: Я также пробовал методы вроде: ExecuteSqlCommand, SqlQuery без помощи.

+0

Я думаю, [это] (http://stackoverflow.com/questions/10339750/entity-framework-stored-procedure-return-value) может помочь. – Shakra

ответ

6

на основе MSDN:

Для UPDATE, INSERT и DELETE заявления, возвращаемое значение является числом строк, затронутых командой. Когда триггер существует в вставленной или обновляемой таблице, возвращаемое значение включает в себя количество строк, затронутых как операцией вставки, так и обновлением, а также количеством строк, затронутых триггером или триггерами. Для всех других типов операторов возвращаемое значение равно -1. Если происходит откат, возвращаемое значение равно -1.

Так ExecuteSqlCommand возвращает Int для запросов как Insert, Update, Delete и это означает, что количество ряда пострадавших одним не-запроса. Так что ExecuteSqlCommand не подходит для запросов.

Также это распространенная проблема, поскольку Entity Framework не может поддерживать хранимую процедуру. Возвращает значения из окна, и это потому, что EF является ORM, а не заменой SQL.Проверьте ссылку для аналогичной задачи в Model First:

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

Но хранимая процедура возвращает xml, используя 'Database.SqlQuery' Он будет возвращать элементы заданного типа, но xml не является примитивным типом. Поправьте меня если я ошибаюсь. –

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 
+0

извините, не в состоянии бросить. – Pearl

+1

@Pearl Проверьте это обновление. –

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 
+0

Не нужно использовать 'EXEC' часть инструкции - просто' xml_test'. –

+0

@TiesonT. tnx, я добавляю примечание об этом;). –

1

Как упомянуто shA.t "FOR XML" может использоваться. Однако при использовании одной вещи нужно усечь строку/XML (возвращенный после вызова функции через EF) размером около 2 тыс. Символов, для обработки этого сценария вы можете посмотреть this. Также, если дизайн кода позволяет, вы можете даже использовать Ouptput parameters with Enitity Framework.

Смежные вопросы