2013-02-17 75 views
15

我剛剛瞭解到一種天才類型,它可以簡化大量工作,但看起來像我的首選ORM無法識別它。SQL Server特定類型支持OrmLite

有什麼解決方法讓ServiceStack OrmLite識別SQL Server中的HierarchyId?任何有關修改哪些文件和任何提示如何繼續的建議?

編輯:

這是問題的一個更好的說明。我有以下類:

public class MyClass 
{ 
    public int Id { get; set; } 
    public SqlHierarchyId HierarchyId { get; set; } 
} 

SqlHierarchyId是一個自定義的SQL Server數據類型。 OrmLite將生成下列類是:

First MyClass Rendering

搞笑的是,我可以使用[StringLength(255)]屬性的屬性,它會得到varchar(255)類型,而不是:

Second MyClass Rendering

我手動在這裏更改表格並添加列數據類型以顯示差異。請注意,第三列的數據類型:

SqlHierarchyId

有一個varchar表示是與其他DBMS爲it can be converted within C#完全正常,但與SQL Server最好是有它匹配相應的數據類型。這將使創建視圖變得更容易(由於hierarchyid數據類型的內置功能)。

我知道該類型不支持EF4(不確定約5)。我還瀏覽了GitHub上的OrmLiteDialectProviderBase.cs文件,我可以看到支持ADO.NET數據類型的列表。

我的一個簡單的問題是:這是ADO.NET的一個強大的限制,或者這可以在OrmLite中看到嗎?如果有任何建議,我願意幫助擴展此部分。

+2

你能展示一個你想要OrmLite支持的東西的SQL +代碼示例嗎? – mythz 2013-02-18 17:23:53

+1

不知道OrmLite做了什麼,但看起來應該匹配字符串類型,因爲它包含像/ 123/234/125這樣的數據。 – RedFilter 2013-12-11 19:14:42

+0

@mythz:請查看已編輯的問題 – 2014-03-03 22:43:58

回答

1

ADO.NET支持hierarchyid類型,可以找到一個示例here並顯示ADO.NET可以直接從Sql Server讀取值作爲hierarchyid,但需要將參數作爲字符串傳遞給服務器。

將對hierarchyid類型方法的支持添加到ORM框架中會破壞ORM API和RDMS之間的抽象。我會認爲這是這樣的功能尚未添加到實體框架的原因。

您可以通過在數據庫中保留層次結構的字符串表示形式,並在您的數據庫和C#類中使用hierarchyid版本作爲計算屬性來解決該問題,則需要將計算出的C#屬性從ORM映射。

例如你的表列將被宣佈爲:

[SqlHierarchyId] AS ([hierarchyid]::Parse([HierarchyId])) PERSISTED 

和類爲:

public class MyClass { 

    public string HierarchyId { 
     get; 
     set; 
    } 

    [Ignore] 
    public SqlHierarchyId SqlHierarchyId { 
     get { 
      return SqlHierarchyId.Parse(new SqlString(HierarchyId)); 
     } 
     set { 
      HierarchyId = value.ToString(); 
     } 
    } 

} 

這將持續從.NET層更新,並允許您使用HIERARCHYID方法在SQL Server中構建查詢並在.Net層中使用物化對象。

你將不得不構造查詢對字符串表示你ORM層,但是這可能仍然利用一些HIERARCHYID輔助方法,例如:

public IEnumerable<MyClass> GetDescendants(MyClass node) { 

    string currentLocation = node.HierarchyId; 
    string followingSibling 
     = node.SqlHierarchyId.GetAncestor(1) 
       .GetDescendant(node.SqlHierarchyId, SqlHierarchyId.Null) 
       .ToString(); 

    return db.Select<MyClass>(n => n.HierarchyId > currentLocation 
           && n.HierarchyId < followingSibling); 

} 

Aplogies如果我已經得到了ORMLite語法錯誤。