2012-12-03 9 views
7

mam DataSet które tworzone przy użyciu rekursji w SQL,Tworzenie XML z hierarchicznego zestawu danych w języku C#

Parent  UserId Child  Reporting_To_UserId Depth  id 
Aditya   13  Abhishek  4     0   13 
Abhishek  4  Saurabh  6     1   16 
Abhishek  4  Mohinder  8     1   17 
Mohinder  8  Mohammad  14     2   18 
Saurabh  6  Rahul  1     2   11 
Saurabh  6  Amitesh  5     2   12 

teraz chcę, aby wygenerować XML, który powinien wyglądać tak: -

<Person name="Aditya" User_Id="13"> 

    <Person name="Abhishek" User_Id="4"> 

      <Person name="Mohinder" User_id="8"> 
       <Person name="Mohammad" User_id="14"/> 
      </Person>   

      <Person name="Saurabh" User_Id="6"> 
       <Person name="Rahul" User_Id="1"/> 
       <Person name="Amitesh" User_Id="5"/> 
      </Person> 

    </Person> 

</Person> 

Chcę utworzyć hierarchiczny XML przy użyciu relacji Rodzic i Dziecko z zestawu danych.

+2

Look do wspólnych wyrażeń tabeli. http://msdn.microsoft.com/en-us/library/ms186243(v=sql.105).aspx – BenCr

+1

Jeśli korzystasz z procedur przechowywanych programu SQL Server, możesz również zwrócić kod XML bezpośrednio z procedury przy użyciu FOR XML EXPLICIT (http://msdn.microsoft.com/en-us/library/ms189068.aspx – bUKaneer

+0

public class Person {List persons {get; set;}} –

Odpowiedz

1

Myślę, że można wykorzystać następujący fragment kodu:

protected void Page_Load(object sender, EventArgs e) 
    { 
     DataSet ds = new DataSet(); 
     string connStr = @"Data Source=MY-PC\SQLExpress;Initial Catalog=DataDB;User Id=ME;Password=YourPassword;Trusted_Connection=True;"; 
     using (SqlConnection conn = new SqlConnection(connStr)) 
     { 
      string sql = "Select MenuID, Text,Description, ParentID from UserInfo"; 
      SqlDataAdapter da = new SqlDataAdapter(sql, conn); 
      da.Fill(ds); 
      da.Dispose(); 
     } 
     ds.DataSetName = "UserInfos"; //You can start directly from here as you have the dataset just mantain Parent and Child ID Proper 
     ds.Tables[0].TableName = "UserInfo"; 
     DataRelation relation = new DataRelation("ParentChild", 
     ds.Tables["UserInfo"].Columns["MenuID"], 
     ds.Tables["UserInfo"].Columns["ParentID"], true); 

     relation.Nested = true; 
     ds.Relations.Add(relation); //XmlDataSource1 is any source of xml you can have this in file also 
     XmlDataSource1.Data = ds.GetXml(); //Here Dataset will automatically generate XML for u based on relations added 

    } 
1

myślę, że można to zrobić z rekurencyjnego LINQ, ale nadal muszę dowiedzieć się, jak napisać dobrze, więc o to rozwiązanie metodą rekurencyjną:

Najpierw zadeklarować metodę (Robiłem wyszukiwanie według Name, ale można też zrobić to z Id):

public static IEnumerable<XElement> BuildXML(string Parent, DataTable dt) 
{ 
    string filter = string.Format("[Parent] = '{0}'", Parent); 
    return from x in dt.Select(filter) 
      select new XElement("Person", 
         new XAttribute("Name", x["Child"]), 
         new XAttribute("User_Id", x["Reporting_To_UserId"]), 
         BuildXML(x["Child"].ToString(), dt) 
        ); 
} 

Następnie należy wywołać go z elementu nadrzędnego (Dodałem górnym rzędzie, inaczej zapytanie będzie bardziej skomplikowane):

var dt = new DataTable(); 
dt.Columns.AddRange(new[] { 
    new DataColumn("Parent"), 
    new DataColumn("UserId"), 
    new DataColumn("Child"), 
    new DataColumn("Reporting_To_UserId"), 
    new DataColumn("Depth"), 
    new DataColumn("id") 
}); 
dt.Rows.Add(new object[] { "", 0, "Aditya", 13, 0, 12 }); 
dt.Rows.Add(new object[] {"Aditya", 13, "Abhishek", 4, 0, 13}); 
dt.Rows.Add(new object[] { "Abhishek", 4, "Saurabh", 6, 1, 16 }); 
dt.Rows.Add(new object[] { "Abhishek", 13, "Mohinder", 8, 1, 17 }); 
dt.Rows.Add(new object[] { "Mohinder", 8, "Mohammad", 14, 2, 18 }); 
dt.Rows.Add(new object[] { "Saurabh", 6, "Rahul", 1, 2, 11 }); 
dt.Rows.Add(new object[] { "Saurabh", 6, "Amitesh", 5, 2, 12 }); 

var result = BuildXML("", dt); 

Teraz masz IEnumerable<XElement>, aby przekształcić go w ciąg, można to zrobić w następujący sposób:

var xml = result. 
      Select(e => e.ToString()). 
      Aggregate((current, next) => current + next); 
0

Można tworzyć DataRelation na w zbiorze , Eg

DataRelation relation = new DataRelation("ParentChild", 
     ds.Tables["UserInfo"].Columns["MenuID"], 
     ds.Tables["UserInfo"].Columns["ParentID"], true); 
**relation.Nested = true;** 
ds.Relations.Add(relation); // 

Powstanie „zagnieżdżony” jest bardzo ważne!

Makeyuan