对OrmLite的SQL Server特定类型支持

Mos*_*aou 15 c# sql sql-server ormlite-servicestack

我刚刚学会了一种天才类型,它可以简化我的大部分工作,但看起来我的首选ORM无法识别它.

是否有一种解决方法让ServiceStack OrmLite HierarchyId在SQL Server中识别?有关要修改哪些文件的任何建议以及任何提示如何继续?

编辑:

这是对问题的更好说明.我有以下课程:

public class MyClass
{
    public int Id { get; set; }
    public SqlHierarchyId HierarchyId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

SqlHierarchyId是一种自定义SQL Server数据类型.OrmLite将为它生成以下类:

第一个MyClass渲染

有趣的是,我可以使用[StringLength(255)]属性上的属性,它将获得varchar(255)类型:

第二个MyClass渲染

我在这里手动更改了表,并添加了列数据类型来展示差异.请注意第三列的数据类型:

SqlHierarchyId

具有varchar表示与其他DBMS完全一样,因为它可以在C#中转换,但是对于SQL Server,最好使它与相应的数据类型匹配.这将使视图的创建更容易(由于hierarchyid数据类型的内置函数).

我知道EF4不支持这种类型(不确定5).我还浏览了GitHub上的OrmLiteDialectProviderBase.cs文件,我可以看到支持的ADO.NET数据类型列表.

我的简单问题是:这是ADO.NET的一个强大限制,还是在OrmLite中可以看到这个?如果提出任何建议,我愿意帮助扩展这一部分.

小智 1

ADO.NET支持hierarchyid类型,可以在此处找到一个示例,该示例显示ADO.NET可以直接从Sql Server读取值作为hierarchyid,但您需要将参数作为字符串传递到服务器。

向 ORM 框架添加对 Hierarchyid 类型方法的支持将打破 ORM API 和 RDMS 之间的抽象。我认为这就是此类功能尚未添加到实体框架的原因。

您可以通过在数据库中保留层次结构的字符串表示形式并将 hierarchyid 版本作为数据库和 C# 类中的计算属性来解决此问题,您需要从 ORM 映射中排除计算的 C# 属性。

例如,您的表列将声明为:

[SqlHierarchyId] AS ([hierarchyid]::Parse([HierarchyId])) PERSISTED 
Run Code Online (Sandbox Code Playgroud)

你的班级为:

public class MyClass {

    public string HierarchyId {
        get;
        set;
    }

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

}
Run Code Online (Sandbox Code Playgroud)

这将保留来自 .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);

}
Run Code Online (Sandbox Code Playgroud)

如果我的 ORMLite 语法错误,请道歉。