C# 从MySQL数据库中提取非平凡对象

C# 从MySQL数据库中提取非平凡对象,c#,mysql,C#,Mysql,我有一个使用MySQL数据库的C#.NET3.5项目 我有一个对象Task,我希望能够通过从一系列数据库表中提取它来创建它 public class Task { public Task() { Values = new List<string>(); OtherValues = new List<string>(); Requirement = string.Empty; Minimum =

我有一个使用MySQL数据库的C#.NET3.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; }
}

这是如何实现的?

您可以将其序列化为XML并将其存储为字符串。将以下功能添加到
任务中

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)
            );
}
您需要使用System.Linq将
放入
使用System.Xml.Linq
位于.cs文件的顶部

我编写代码不是为了序列化
子对象
,因为我不知道数据类型
Foo
是什么样子,但您应该以类似的方式序列化它。完成后,您可以轻松地将XML写入数据库,并将其读回(编写一个将XML解析为任务对象的构造函数)

编辑(添加)
以下是接收XML(或将字符串解析为XML)的构造函数的示例:

编辑(解释)
不能将对象按原样存储在数据库“原样”中,因为它引用了其他对象。例如-列表
与对象的其余部分不在内存中的同一位置,因为它是ref类型-它引用位于内存中不同位置的另一个对象。事实上,对象中与主对象存储在同一位置的唯一部分是
最小值
最大值
,它们是ref类型,因此,如果您能够以某种方式按原样存储对象(如果可行,则可能是最懒的解决方案),您将获得正确的最小值和最大值字段,但所有其他字段都将指向存储任务对象时这些对象所在的内存地址,它们现在很可能是无效指针(我说“最有可能”,因为它们也可能(尽管很少)指向合法对象,可能是相同类型的事件,但它们仍然没有您的数据

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

Xml还具有易于从大多数现代编程语言和数据库引擎读取的优点,因此您可以更新数据库中的对象,并通过MySQL查询访问其字段

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

  • 如果你想要一些简单高效的东西,即使代价是失去兼容性,也可以将你的对象序列化为二进制

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

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


这是您计划对数据库执行的唯一操作吗?否则,我强烈建议您使用OR/M工具。@GertArnold-正如您从我的其他问题中看到的,我尝试使用OR/M工具失败。我并不总是阅读OPs中的其他问题:)。但是,嘿,那太糟糕了。我知道NHibernate在MySql上有一些问题,但是很多!您的意思是将整个对象放入数据库中编码为XML的单个字符串类型列中?我不想那样做。1.因为我想在必要时延迟加载元素。2.因为拉入所有这些额外的XML将是无性能的。3.因为我会丢失所有的数据库优化,比如顺序和选择位置。这是一个懒惰的解决方案。对此的解释相当长,因此我将其添加到了答案中。
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)
            );
}
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);
}