从 MySQL 数据库中提取一个重要的对象
本文关键字:一个 重要的 对象 MySQL 数据库 提取 | 更新日期: 2023-09-27 18:10:41
我有一个使用 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 /* ??? */
}
}
}
}
这是怎么做到的?
您可以将其序列化为 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);
}
编辑(说明(:
不能将对象按原样存储在数据库中,因为它引用其他对象。例如 - 列表Values
与对象的其余部分不在内存中的同一位置,因为它是一种 ref 类型 - 它指的是位于内存中不同位置的另一个对象。事实上,对象中唯一与主对象存储在同一位置的部分是 Minimum
和 Maximum
,它们是 ref 类型,所以如果你能以某种方式按原样存储对象(最懒惰的解决方案,如果它有效(,你会得到你的最小值和最大值字段正确, 但是所有其他字段都将指向存储 Task 对象时放置这些对象的内存地址,这些对象现在很可能是无效指针(我说"最有可能",因为它们也有可能(尽管很少见(指向合法对象,可能是相同类型的事件 - 但它们仍然不会有您的数据。
如果你想让对象及其所有数据存储在数据库中(或存储在文件中,或者传递给通过网络在另一台计算机上运行的进程(,你必须序列化它。在性能方面,最好的方法是将其序列化为二进制(C#有一些工具,但它仍然比XML更复杂(。
XML 还具有从大多数现代编程语言和数据库引擎中轻松读取的缺点。MySQL具有一些读取和写入XML的函数,因此您可以更新数据库中的对象并从MySQL查询访问其字段。
结论
您要求一个简单(懒惰(、高效且与 sql 兼容(从 MySQL 查询访问对象字段(的解决方案。我说你只能有三个要求中的两个,但你可以选择哪两个:
如果你想要一些简单高效的东西,即使以失去兼容性为代价,也可以将对象序列化为二进制。诚然,它不像XML那么容易,但是.NET有一些工具来帮助你。
如果你想要一些高效和兼容的东西,并且愿意为此做一些工作,你可以把你的对象放在MySQL中,就像数据库的使用方式一样 - 为通过OID引用对象的列表使用单独的表,等等。这将需要一些工作,但是在添加表并编码MySQL函数和处理所有内容的C#函数之后,您应该能够轻松存储,检索和访问对象。
如果您想要一些简单且兼容的东西,并且您可以承受一些效率的损失,请使用我的解决方案并将您的对象序列化为 XML。这是最懒惰的解决方案 - 除非有人知道可以自动序列化任何对象的库,否则 LINQ to XML 是最简单的方法,并且比任何其他解决方案需要的代码少得多。