15

我刚刚了解了一种天才类型,它可以简化我的很多工作,但看起来我首选的 ORM 无法识别它。

是否有让 ServiceStack OrmLiteHierarchyId在 SQL Server 中识别的解决方法?关于修改哪些文件的任何建议以及如何进行的任何提示?

编辑 :

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

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

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 中看到?如果有任何建议,我愿意帮助扩展这部分。

4

1 回答 1

1

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

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

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

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

[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);

}

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

于 2015-02-25T05:12:47.150 回答