对 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)