2011-10-06 58 views
2

我有一個使用MySQL數據庫的C#.NET 3.5項目。從MySQL數據庫中提取一個不重要的對象

我有一個對象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

這是您計劃用數據庫做的唯一事情嗎?否則,我會強烈建議您使用OR/M工具。 –

+0

@GertArnold - 正如你從其他問題中看到的,我對OR/M工具的嘗試遇到了失敗。 – PaulH

+0

我並不總是閱讀OP的其他問題:)。但是,嘿,那太糟糕了。我知道NHibernate有一些與MySql有關的問題,但是有很多! –

回答

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到任務對象的構造)

EDIT(加)
這裏是一個例如,以接收XML一個構造函數(或解析字符串爲XML):

​​

EDIT(解釋)
你無法保存您的對象是在數據庫中的「原樣」 ,因爲它指的是其他對象TS。例如 - 列表Values不與對象的其餘部分位於內存中的相同位置,因爲它是ref類型 - 它指向位於內存中不同位置的另一個對象。事實上,對象的唯一部分與主對象存儲在同一個地方,它們是MinimumMaximum,它們都是ref類型,所以如果你能以某種方式存儲對象(最懶的解決方案,如果它可能的話)工作),你會得到你的最小和最大字段的權利,但所有其他領域將指向內存地址的地方,當你存儲任務對象,現在最有可能是無效指針(我說「最有可能」因爲它也有可能(儘管很少)指向合法對象,可能是同一類型的事件 - 但它們仍然不會有數據。

如果您希望包含所有數據的對象存儲在一個數據庫中(或者在一個文件中,或者傳遞給通過網絡在另一臺計算機上運行的進程)y你必須要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到XML是做到這一點的最簡單的方法,並且需要比任何其他解決方案更少的代碼。

+0

你的意思是把整個對象放在數據庫中的單個字符串類型的列中,編碼爲XML?我寧願不這樣做。 1.因爲我想在必要時延遲加載元素。 2.因爲拉入所有額外的XML將是非高性能的。 3.因爲我會失去所有的數據庫優化,如ORDER和SELECT WHERE。 – PaulH

+0

這*是懶惰的解決方案。對此的解釋相當長,所以我將其添加到答案中。 –