对 OrmLite 的 SQL Server 特定类型支持

Posted

技术标签:

【中文标题】对 OrmLite 的 SQL Server 特定类型支持【英文标题】:SQL Server specific types support for OrmLite 【发布时间】:2013-02-02 04:01:30 【问题描述】:

我刚刚了解到一种天才类型,它可以简化我的很多工作,但我喜欢的 ORM 似乎无法识别它。

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

编辑:

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

public class MyClass

    public int Id  get; set; 
    public SqlHierarchyId HierarchyId  get; set; 

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

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

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

拥有varchar 表示对于其他DBMS 来说是非常好的it can be converted within C#,但是对于SQL Server,最好让它匹配相应的数据类型。这将使视图的创建更容易(由于 hierarchyid 数据类型的内置函数)。

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

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

【问题讨论】:

您能否展示一个您希望 OrmLite 支持的 SQL + 代码示例? 不确定 OrmLite 做了什么,但它看起来应该与字符串类型匹配,因为它包含像 /123/234/125 这样的数据。 @mythz:请看一下编辑后的问题 @MoslemBenDhaou 你可以使用新的Custom Field Declarations 来做你想做的事。否则,您可以添加 feature request for it,但专门的 RDBMS 支持不太可能成为流行的功能请求,因此优先级较低。 不想成为热门话题,但我会避免 HierarchyId。我曾一度考虑将 HierarchyId 用于我的应用程序,但在看到性能有多糟糕后我感到很失望。查看this presentation by Louis Davidson,它对不同层次结构设置进行了全面的性能比较(尤其是幻灯片 44)。 【参考方案1】:

ADO.NET 支持 hierarchyid 类型,可以找到一个示例 here 并显示 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 语法有误,请致歉。

【讨论】:

以上是关于对 OrmLite 的 SQL Server 特定类型支持的主要内容,如果未能解决你的问题,请参考以下文章

如何修改 ServiceStack.OrmLite 生成的 SQL?

VeraCode 报告 ServiceStack OrmLite 对 SQL 命令中使用的特殊元素进行了不当中和(“SQL 注入”)(CWE ID 89)

Ormlite数据库

SQL SERVER中隐式转换的一些细节浅析

SQL SERVER中隐式转换的一些细节浅析

ServiceStack OrmLite SQL 错误?