c# - 从 MySQL 数据库中提取一个非平凡的对象

标签 c# mysql

我有一个使用 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 类型 - 它引用另一个对象,该对象位于内存中的不同位置.事实上,你的对象中唯一与主对象存储在同一位置的部分是 MinimumMaximum,它们是 ref 类型,所以如果你可以以某种方式按原样存储对象(可能是最懒惰的解决方案,如果可行的话),您将获得正确的最小值和最大值字段,但所有其他字段将指向存储任务对象时放置这些对象的内存地址,这现在很可能是无效指针(我说“最有可能”是因为它们也有可能(尽管很少见)指向合法对象,可能是同一类型的事件——但它们仍然不会有你的 数据。

如果您希望将对象及其所有数据存储在数据库中(或文件中。或通过网络传递给在另一台计算机上运行的进程),您必须 serialize它。就性能而言,最好的方法是将其序列化为二进制(C# 有一些工具,但它仍然比 XML 更复杂)。

Xml 还具有易于从大多数现代编程语言和数据库引擎读取的优势。 MySQL has some functions to read and write XML ,因此您可以更新数据库中的对象并从 MySQL 查询访问它的字段。

结论
您要求一个简单(惰性)、高效且与 sql 兼容(从 MySQL 查询访问对象字段)的解决方案。我说你只能有你的三个要求中的两个,但你可以选择哪两个:

  • 如果您想要简单高效的东西,即使以失去兼容性为代价,请将您的对象序列化为二进制。的确,它不像 XML 那样简单,但是 .NET has some tools to help you with that .

  • 如果您想要一些高效且兼容的东西,并且愿意为此做一些工作,您可以按照数据库的使用方式将您的对象放入 MySQL - 为引用对象的列表使用单独的表通过 OID 等。这需要一些工作,但是在您添加表并编写 MySQL 函数和处理所有内容的 C# 函数之后,您应该能够轻松地存储、检索和访问您的对象。

  • 如果您想要一些简单且兼容的东西,并且您可以承受损失一些效率,请使用我的解决方案并将您的对象序列化为 XML。此是最懒惰的解决方案 - 除非有人知道可以自动序列化任何对象的库,否则 LINQ to XML 是最简单的方法,并且比任何其他解决方案需要的代码少得多。

关于c# - 从 MySQL 数据库中提取一个非平凡的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7679553/

相关文章:

c# - 绑定(bind)到 MainView 窗口的 Width 属性时出现绑定(bind)错误

c# - 自定义 json contractresolver .net web api 在某些情况下回落到 camelcase

php - laravel 从数据库中获取 microtime

c# - 从 MySql 数据库收集数据后,我的 ASP.NET 应用程序不显示填充的 GridView

php - 如何高效更新10万条记录的MySQL数据库

c# - 获取临时键 x 和 y 坐标

c# - .NET Core DI,将参数传递给构造函数的方法

c# - 如何从IObservable请求商品?

javascript - 如何在提交后使 php 表单只读并在同一页面上单击编辑可编辑?

mysql - 如何连接 MySQL 表?