在对.NET核心使用SqlGeography在ServiceStack.OrmLite

问题描述 投票:2回答:2

我尝试SqlGeography添加到我的模型,当我打电话创建表我有奇怪的错误。

首先,我加入这个包:Microsoft.SqlServer.Types

然后,我在下面创建我的模型像例如:

public class Locations 
{
   public int Id { get; set; }
   public string Name { get; set; }
   public SqlGeography Location { get; set; }
}

然后调用CreateTableIfNotExists创建表

private void CheckDB(IDbConnectionFactory dbConnectionFactory)
{
    using (var db = dbConnectionFactory.Open())
    {
        db.CreateTableIfNotExists<Models.Entities.DbIpEntity>();
    }
}

而在结束时,我得到这个错误:

System.TypeLoadException的HResult = 0x80131522消息=无法从组件加载类型 'Microsoft.SqlServer.Server.IBinarySerialize' 'System.Data,版本= 4.0.0.0,文化=中性公钥= b77a5c561934e089'。来源= System.Private.CoreLib 堆栈跟踪:在System.Signature.GetSignature(void *的pCorSig,的Int32 cCorSig,RuntimeFieldHandleInternal fieldHandle,IRuntimeMethodInfo methodHandle,RuntimeType declaringType)在System.Reflection.RuntimeMethodInfo.FetchNonReturnParameters()在System.Reflection.RuntimeMethodInfo.GetParametersNoCopy()在的System.Reflection。 RuntimePropertyInfo.GetIndexParametersNoCopy()在System.Reflection.RuntimePropertyInfo.GetIndexParameters()在ServiceStack.OrmLite.OrmLiteConfigExtensions.GetModelDefinition(类型modelType)在ServiceStack.OrmLite.OrmLiteWriteCommandExtensions.CreateTable(IDbCommand的dbCmd,布尔重写,类型modelType)在ServiceStack.OrmLite。 OrmLiteExecFilter.Exec [T](的IDbConnection dbConn,Func`2滤波器)在ServiceStack.OrmLite.OrmLiteSchemaApi.DropAndCreateTable [T](的IDbConnection dbConn)在GeoApi.AppHost.CheckDB(IDbConnectionFactory dbConnectionFactory)在E:\项目\地理位置\ APPHOST。 CS:\项目\地理位置\ AppHost.cs:在GeoApi.AppHost.Configure(容器容器)在E行48线40一吨ServiceStack.ServiceStackHost.Init()在ServiceStack.NetCoreAppHostExtensions.UseServiceStack(IApplicationBuilder应用程序,AppHostBase APPHOST)在GeoApi.Startup.Configure(IApplicationBuilder应用程序,IHostingEnvironment ENV)在E:\项目\地理位置\ Startup.cs:线49

在这种错误,我意识到它是寻找.NET Framework程序集(System.Data, Version=4.0.0.0)未对.NET核心

c# .net-core servicestack ormlite-servicestack
2个回答
2
投票

其中ServiceStack.OrmLite.SqlServer.Converters定义的Microsoft.SqlServer.TypesSqlGeography仅可用于.NET V4.5和分别.NET V4.0所以它至少需要.NET V4.5的运行,并且不能在.NET核心中使用。


2
投票

.NET 2.2的核心现在支持地理空间数据的工作 - https://docs.microsoft.com/en-us/ef/core/modeling/spatial

我能拼凑自己OrmLiteConverter各地the SqlServerGeographyTypeConverter here.基于

public class SqlServerIPointTypeConverter : OrmLiteConverter
{
    public override string ColumnDefinition => "geography";
    public override DbType DbType => DbType.Object;

    public override string ToQuotedString(Type fieldType, object value)
    {
        if (fieldType != typeof(IPoint)) return base.ToQuotedString(fieldType, value);

        string str = null;
        if (value != null)
        {
            var geo = (IPoint) value;
            str = geo.ToString();
        }

        str = (str == null) ? "null" : $"'{str}'";
        return $"CAST({str} AS {ColumnDefinition})";
    }

    public override void InitDbParam(IDbDataParameter p, Type fieldType)
    {
        if (fieldType == typeof(IPoint))
        {
            var sqlParam = (SqlParameter)p;
            sqlParam.IsNullable = fieldType.IsNullableType();
            sqlParam.SqlDbType = SqlDbType.Udt;
            sqlParam.UdtTypeName = ColumnDefinition;
        }

        base.InitDbParam(p, fieldType);
    }

    public override object FromDbValue(Type fieldType, object value)
    {
        switch (value)
        {
            case null:
            case DBNull _:
                return new Point(0, 0);
            case IPoint point:
                return point;
            case string _:
                return Parse(value.ToString());
            default:
                return base.FromDbValue(fieldType, value);
        }
    }

    public override object ToDbValue(Type fieldType, object value)
    {
        switch (value)
        {
            case null:
            case DBNull _:
                return new Point(0, 0);
            case IPoint _:
                return value;
            case string str:
                return Parse(str);
            default:
                return base.ToDbValue(fieldType, value);
        }
    }

    private static Point Parse(string rawPoint)
    {
        var split = rawPoint.Replace("POINT (", string.Empty)
            .Replace(")", string.Empty)
            .Trim()
            .Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);

        var longitude = Convert.ToDouble(split[0]);
        var latitude = Convert.ToDouble(split[1]);

        return new Point(longitude, latitude);
    }
}

然后在您的APPHOST文件:

SqlServerDialect.Provider.RegisterConverter<Point>(new SqlServerIPointTypeConverter());

只要你在DOTNET核心2.2,并具有以下的NuGet包引用,它应该工作:

© www.soinside.com 2019 - 2024. All rights reserved.