SQL Server specific types support for OrmLite

别说谁变了你拦得住时间么 提交于 2019-12-22 01:42:59

问题


I just learned about a genius type that would simplify a lot of my work but it looks like my preferred ORM does not recognize it.

Is there a workaround to let ServiceStack OrmLite recognize HierarchyId in SQL Server? Any suggestions about which files to modify and any hints how to proceed?

EDIT :

Here is a better illustration of the problem. I have the following class:

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

SqlHierarchyId is a custom SQL Server data type. OrmLite will generate the following class for it:

Funny enough, I can use the [StringLength(255)] attribute on the property and it will get the varchar(255) type instead:

I manually changed the table here and added the column data type to showcase the difference. Please note the data type of the third column:

Having a varchar representation is perfectly fine with other DBMS as it can be converted within C#, but with SQL Server it is preferable to have it match the corresponding data type. This will make the creation of views easier (due to the built-in functions of the hierarchyid data type).

I know the type is not supported by EF4 (not sure about 5). I also browsed the OrmLiteDialectProviderBase.cs file on GitHub and I can see a list of supported ADO.NET data types.

My simple question is: Is this a strong limitation by ADO.NET or this can be seen sometime in OrmLite? I am willing to help extending this part if any suggestions are made.


回答1:


ADO.NET has support for the hierarchyid type, an example can be found here and shows ADO.NET can read values from Sql Server as a hierarchyid directly but you need to pass parameters to the server as a string.

Adding support for the hierarchyid type methods to a ORM framework would break the abstraction between the ORM API and the RDMS. I would assume this is the reason such functionality has not been added to Entity Framework.

You could work around the issue by keeping a string representation of the hierarchy in your database and having the hierarchyid version as a computed property in both your database and your C# class, you would need to exclude the computed C# property from the ORM mapping.

For example your table column would be declared as:

[SqlHierarchyId] AS ([hierarchyid]::Parse([HierarchyId])) PERSISTED 

and your class as:

public class MyClass {

    public string HierarchyId {
        get;
        set;
    }

    [Ignore]
    public SqlHierarchyId SqlHierarchyId {
        get {
            return SqlHierarchyId.Parse(new SqlString(HierarchyId));
        }
        set {
            HierarchyId = value.ToString();
        }
    }

}

This will persisted updates from the .Net layer and allow you to use the hierarchyid methods to construct queries in SQL Server and work with materialised objects in the .Net layer.

You would have to construct queries against the string representation in you ORM layer but this could still leverage some of the hierarchyid helper methods, for example:

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

}

Aplogies if I have got the ORMLite syntax wrong.



来源:https://stackoverflow.com/questions/14924173/sql-server-specific-types-support-for-ormlite

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!