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将为它生成以下类:

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

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

具有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 语法错误,请道歉。