我刚刚了解了一种天才类型,它可以简化我的很多工作,但我喜欢的 ORM 似乎无法识别它。
是否有解决方法让 ServiceStack OrmLite 识别 SQL Server 中的 HierarchyId
?关于修改哪些文件的任何建议以及如何进行的任何提示?
编辑:
这是对问题的更好说明。我有以下类(class):
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,最好让它匹配相应的数据类型。这将使 View 的创建更容易(由于 hierarchyid
数据类型的内置函数)。
我知道 EF4 不支持该类型(不确定 5)。我还浏览了 OrmLiteDialectProviderBase.cs GitHub 上的文件,我可以看到支持的 ADO.NET 数据类型列表。
我的简单问题是:这是 ADO.NET 的强烈限制还是有时可以在 OrmLite 中看到?如果有任何建议,我愿意帮助扩展这部分。
最佳答案
ADO.NET 支持 hierarchyid 类型,可以找到示例 here并显示 ADO.NET 可以直接从 Sql Server 读取值作为 hierarchyid,但您需要将参数作为字符串传递给服务器。
向 ORM 框架添加对 hierarchyid 类型方法的支持会破坏 ORM API 和 RDMS 之间的抽象。我认为这就是此类功能尚未添加到 Entity Framework 的原因。
您可以通过在数据库中保留层次结构的字符串表示形式并将 hierarchyid 版本作为数据库和 C# 类中的计算属性来解决此问题,您需要从 ORM 中排除计算的 C# 属性映射。
例如,您的表格列将声明为:
[SqlHierarchyId] AS ([hierarchyid]::Parse([HierarchyId])) PERSISTED
你的类(class)是:
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 语法,我深表歉意。
关于c# - SQL Server 特定类型支持 OrmLite,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14924173/