Pase la lista como XElement para usar como parámetro de tipo de datos XML

I have a stored procedure in SQL Server

CREATE PROCEDURE ParseXML (@InputXML xml)

The data type for input parameter is “xml”.

In the LINQ to SQL generated code for the stored procedure the input parameter is System.Xml.Linq.XElement

[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.ParseXML")]
public ISingleResult<ParseXMLResult> ParseXML([global::System.Data.Linq.Mapping.ParameterAttribute(Name="InputXML", DbType="Xml")] System.Xml.Linq.XElement inputXML)

Now, how can I pass the following List to the ParseXML method to make the stored procedure work?

EDITAR:

After reading the answer - another solution is listed below

XElement root = new XElement("ArrayOfBankAccountDTOForStatus",
new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
new XAttribute(XNamespace.Xmlns + "xsd", "http://www.w3.org/2001/XMLSchema"));


foreach (var element in bankAccountDTOList)
{

 XElement ex= new XElement("BankAccountDTOForStatus", 
                      new XElement("BankAccountID", element.BankAccountID),
                      new XElement("Status", element.Status));


 root.Add(ex);
} 

CODE In Question

        string connectionstring = "Data Source=.;Initial Catalog=LibraryReservationSystem;Integrated Security=True;Connect Timeout=30";
        var theDataContext = new DBML_Project.MyDataClassesDataContext(connectionstring);

        List<DTOLayer.BankAccountDTOForStatus> bankAccountDTOList = new List<DTOLayer.BankAccountDTOForStatus>();
        DTOLayer.BankAccountDTOForStatus presentAccount1 = new DTOLayer.BankAccountDTOForStatus();
        presentAccount1.BankAccountID = 5;
        presentAccount1.Status = "FrozenF13";

        DTOLayer.BankAccountDTOForStatus presentAccount2 = new DTOLayer.BankAccountDTOForStatus();
        presentAccount2.BankAccountID = 6;
        presentAccount2.Status = "FrozenF23";
        bankAccountDTOList.Add(presentAccount1);
        bankAccountDTOList.Add(presentAccount2);

        //theDataContext.ParseXML(inputXML);

Required XML Structure

enter image description here

Note: This XML is used for some operations, not for directly storing in database as XML. I need to write a select query that will list the data from the XML.

Stored Procedure Logic

DECLARE @MyTable TABLE (RowNumber int, BankAccountID int, StatusVal varchar(max))

INSERT INTO @MyTable(RowNumber, BankAccountID,StatusVal)

SELECT ROW_NUMBER() OVER(ORDER BY c.value('BankAccountID[1]','int') ASC) AS Row,
    c.value('BankAccountID[1]','int'),
    c.value('Status[1]','varchar(32)')
FROM
    @inputXML.nodes('//BankAccountDTOForStatus') T(c);

LECTURA

  1. Cómo serializar y guardar un objeto en la base de datos como Xml usando Linq to SQL

  2. Cómo usar una consulta LINQ para obtener valores de XElement cuando XElements tienen el mismo nombre

  3. Linq-to-SQL con campos de base de datos XML: ¿por qué funciona?

  4. http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=176385

preguntado el 04 de julio de 12 a las 08:07

2 Respuestas

You can turn your list into an XML fragment like this:

        IEnumerable<XElement> el = list.Select(i => 
                            new XElement("BankAccountDTOForStatus", 
                              new XElement("BankAccountID", i.BankAccountID),
                              new XElement("Status", i.Status)
                            ));

Then you can turn it into an XElement:

        XElement root = new XElement("root", el);

Now you can just pass it to ParseXML as parameter inputXML which is of type XElement. In stored procedure handle it like this:

DECLARE @InputXML NVARCHAR(1024) = N'
<root>
 <BankAccountDTOForStatus>
     <BankAccountID>2</BankAccountID>
     <Status>FrozenFA</Status>
 </BankAccountDTOForStatus>
 <BankAccountDTOForStatus>
     <BankAccountID>3</BankAccountID>
     <Status>FrozenSB</Status>
 </BankAccountDTOForStatus>
</root>'

DECLARE @handle INT

EXEC sp_xml_preparedocument @handle OUTPUT, @InputXML

SELECT  *
FROM    OPENXML(@handle, '/root/BankAccountDTOForStatus', 1)
WITH    (
            BankAccountID INT 'BankAccountID/text()',
            Status VARCHAR(128) 'Status/text()'
)

EXEC sp_xml_removedocument @handle

Respondido 04 Jul 12, 09:07

Necesitas algo como esto:

  • define your input XML - e.g. as a string
  • convert that to a XDocument
  • pasa el XDocument.Root into the ParseXML method on your Linq-to-SQL data context

Entonces su código sería algo como esto:

// define input XML - e.g. load from file or whatever
string xmlInput =
            @"<ArrayOfBankAccountDTOForStatus>
                         <BankAccountDTOForStatus>
                             <BankAccountID>2</BankAccountID>
                             <Status>FrozenFA</Status>
                         </BankAccountDTOForStatus>
                         <BankAccountDTOForStatus>
                             <BankAccountID>3</BankAccountID>
                             <Status>FrozenSB</Status>
                         </BankAccountDTOForStatus>
                     </ArrayOfBankAccountDTOForStatus>";

// convert that into a XDocument
XDocument doc = XDocument.Parse(xmlInput);

// using your DataContext - call ParseXML
using (DataClasses1DataContext ctx = new DataClasses1DataContext())
{
    var result = ctx.ParseXML(doc.Root);
}

And that's it! Now your XML is being passed to the stored procedure and dealt with there.

Respondido 04 Jul 12, 08:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.