我有一个使用MySQL数据库的C#.NET 3.5项目。
我有一个对象Task
,我希望能够通过从一系列数据库表中提取它来创建它。
public class Task
{
public Task()
{
Values = new List<string>();
OtherValues = new List<string>();
Requirement = string.Empty;
Minimum = 1;
Children = new List<Foo>();
}
public IList<string> Values { get; set; }
public IList<string> OtherValues { get; set; }
public string Requirement { get; set; }
public int Minimum { get; set; }
public int Maximum { get; set; }
public IList<Foo> Children { get; set; }
}
我希望能够从TaskList
获取任务,这些任务会在枚举器访问时懒惰地读取任务的元素。
public class TaskList : IEnumerable<Task>
{
/* ... */
public IEnumerator<Task> GetEnumerator()
{
string query = @"SELECT my_task.*, `Order` FROM my_task ORDER BY `Order` DESC";
using (MySqlConnection connection = new MySqlConnection(connection_string_))
using (MySqlCommand command = connection.CreateCommand())
{
command.CommandText = query;
connection.Open();
using (MySqlDataReader reader = command.ExecuteReader())
{
yeild /* ??? */
}
}
}
}
这是怎么做到的?
答案 0 :(得分:1)
您可以将其序列化为XML并将其存储为字符串。将以下函数添加到Task
:
public XElement Serialize()
{
return new XElement("Task",
new XElement("Values",from val in Values select new XElement("Item",val)),
new XElement("OtherValues",from val in OtherValues select new XElement("Item",val)),
new XElement("Requirement",Requirement),
new XElement("Minimum",Minimum),
new XElement("Maximum",Maximum)
);
}
您需要将using System.Linq;
和using System.Xml.Linq;
放在.cs文件的顶部。
我没有编写序列化Children
的代码,因为我不知道数据类型Foo
是什么样的,但您应该以类似的方式对其进行序列化。完成之后,您可以轻松地将XML写入数据库,然后将其读回(编写一个将Xml解析为Task对象的构造函数)
修改(添加)强>:
以下是接收XML(或将字符串解析为XML)的构造函数的示例:
public Task(string xmlSourceAsString):
this(XElement.Parse(xmlSourceAsString))
{
}
public Task(XElement xmlSource)
{
Values=(from itm in xmlSource.Element("Values").Elements("Item") select itm.Value).ToList();
OtherValues=(from itm in xmlSource.Element("OtherValues").Elements("Item") select itm.Value).ToList();
Requirement=xmlSource.Element("Requirement").Value;
Minimum=int.Parse(xmlSource.Element("Minimum").Value);
Maximum=int.Parse(xmlSource.Element("Maximum").Value);
}
修改(解释)强>: 如果您希望对象的所有数据存储在数据库中(或在文件中。或传递给通过网络在另一台计算机上运行的进程),则必须serialize它。在性能方面,最好的方法是将其序列化为二进制(C#有一些工具,但它仍然比XML复杂。) Xml还具有从大多数现代编程语言和数据库引擎中轻松读取的优势。 MySQL has some functions to read and write XML,因此您可以更新数据库中的对象并从MySQL查询中访问它的字段。 <强>结论强> 如果您想要简单高效的东西,即使以失去兼容性为代价,也可以将对象序列化为二进制。没错,它不像XML那么简单,只有.NET has some tools to help you with that。 如果你想要一些有效且兼容的东西,并愿意为此做一些工作,你可以按照数据库的使用方式将你的对象放在MySQL中 - 对引用对象的列表使用单独的表通过OID等等。这需要一些工作,但是在添加表和代码MySQL函数以及处理所有内容的C#函数之后,您应该能够轻松地存储,检索和访问对象。 如果您想要简单且兼容的东西,并且可以放弃一些效率,请使用我的解决方案并将对象序列化为XML。这个是最懒的解决方案 - 除非有人知道可以自动序列化任何对象的库,LINQ to XML是最简单的方法,并且需要的代码比任何其他解决方案少得多。
您不能将对象“按原样”存储在数据库中,因为它引用其他对象。例如 - 列表Values
与对象的其余部分不在内存中,因为它是ref类型 - 它指的是位于内存中不同位置的另一个对象。事实上,对象中与主对象存储在同一位置的唯一部分是Minimum
和Maximum
,它们是ref类型,所以如果你能以某种方式将对象存储为是(最懒的解决方案,如果它工作),你会得到你的最小和最大字段,但所有其他字段将指向存储Task对象时放置的那些对象的内存地址,这些对象现在很可能是无效指针(我说“最有可能”,因为它们也可能(尽管很少见)它们会指向合法的对象,也许是相同类型的事件 - 但它们仍然没有你的数据。 / p>
您要求一个简单(懒惰),高效和sql兼容的解决方案(从MySQL查询访问对象的字段)。我说你只能有三个要求中的两个,但你可以选择哪两个: