У меня есть DataSet
, состоящий из Authors
и Books
. Автор может иметь несколько книг. Книга может иметь несколько авторов. Итак, у меня есть таблица соединений AuthorBook
. Я хотел бы сериализовать это в XML во вложенном виде.
Мой желаемый результат будет:
<MyDataSet>
<Authors>
<AuthorID>0</AuthorID>
<Name>Anne Rice</Name>
<Books>
<Title>Interview with the vampire</Title>
</Books>
<Books>
<Title>The vampire Armand</Title>
</Books>
</Authors>
<Authors>
<AuthorID>1</AuthorID>
<Name>Stephen J Gould</Name>
<Books>
<Title>Wonderful life</Title>
</Books>
</Authors>
...
</MyDataSet>
Для иллюстрации у меня есть следующий код:
static void Main(string[] args)
{
DataSet ds = CreateDataSet();
PopulateDataSet(ds);
ds.WriteXml(@"e:\temp\demo.xml");
Console.WriteLine("Done");
Console.Read();
}
static DataSet CreateDataSet()
{
DataSet ds = new DataSet("MyDataSet");
DataTable dt;
DataColumn dc;
// add authors table
dt = new DataTable("Authors");
dc = dt.Columns.Add("AuthorID", typeof(int));
dc.AutoIncrement = true;
dc.ReadOnly = true;
dc = dt.Columns.Add("Name", typeof(string));
dt.PrimaryKey = new DataColumn[] { dt.Columns["AuthorID"] };
ds.Tables.Add(dt);
// add books table
dt = new DataTable("Books");
dc = dt.Columns.Add("BookID", typeof(int));
dc.AutoIncrement = true;
dc.ReadOnly = true;
dc = dt.Columns.Add("Title", typeof(string));
dt.PrimaryKey = new DataColumn[] { dt.Columns["BookID"] };
ds.Tables.Add(dt);
// add link table
dt = new DataTable("AuthorBook");
dt.Columns.Add("AuthorID", typeof(int));
dt.Columns.Add("BookID", typeof(int));
dt.PrimaryKey = new DataColumn[] { dt.Columns["AuthorID"], dt.Columns["BookID"] };
ds.Tables.Add(dt);
// define relations: Authors has children in join table
var r = ds.Relations.Add("AuthorsBooks",
ds.Tables["Authors"].Columns["AuthorID"],
ds.Tables["AuthorBook"].Columns["AuthorID"],
true);
r.Nested = true;
// define relations: Books has children in join table
r = ds.Relations.Add("BooksAuthors",
ds.Tables["Books"].Columns["BookID"],
ds.Tables["AuthorBook"].Columns["BookID"],
true);
r.Nested = true;
return ds;
}
static void PopulateDataSet(DataSet ds)
{
IList<string> authors = new List<string>() { "Anne Rice", "Stephen J Gould" };
IList<string> books = new List<string>() { "Interview with the vampire", "The vampire Armand", "Wonderful life" };
foreach (string s in authors)
{
DataRow row = ds.Tables["Authors"].NewRow();
row["Name"] = s;
ds.Tables["Authors"].Rows.Add(row);
}
foreach (string s in books)
{
DataRow row = ds.Tables["Books"].NewRow();
row["Title"] = s;
ds.Tables["Books"].Rows.Add(row);
}
// populate link table. Strictly arbitrary, just to have some data
DataRow jtrow = ds.Tables["AuthorBook"].NewRow();
jtrow["AuthorID"] = 0; // Anne Rice
jtrow["BookID"] = 0; // Interview with the vampire
ds.Tables["AuthorBook"].Rows.Add(jtrow);
jtrow = ds.Tables["AuthorBook"].NewRow();
jtrow["AuthorID"] = 0; // Anne Rice
jtrow["BookID"] = 1; // The vampire Armand
ds.Tables["AuthorBook"].Rows.Add(jtrow);
jtrow = ds.Tables["AuthorBook"].NewRow();
jtrow["AuthorID"] = 1; // Stephen J Gould
jtrow["BookID"] = 2; // Wonderful life
ds.Tables["AuthorBook"].Rows.Add(jtrow);
}
Этот код выдаст ошибку: Cannot proceed with serializing DataTable 'AuthorBook'. It contains a DataRow which has multiple parent rows on the same Foreign Key.
Я могу установить свойство Nested
любого (или обоих) отношений на false
, но это приведет к тому, что сама таблица соединения будет вложенный в мои выходные данные, или, если оба ложные, я просто получаю все данные «линейным» образом, из-за отсутствия лучшего слова.
Я довольно новичок в этом, и я чувствую, что мне не хватает часть головоломки. Пожалуйста, сообщите, спасибо.