Commit 6600c66b authored by Marc Gravell's avatar Marc Gravell

Support SqlGeography as well as DbGeography

parent 8fcb8ebb
...@@ -60,6 +60,9 @@ ...@@ -60,6 +60,9 @@
<Compile Include="..\Dapper.EntityFramework NET45\Handlers.cs"> <Compile Include="..\Dapper.EntityFramework NET45\Handlers.cs">
<Link>Handlers.cs</Link> <Link>Handlers.cs</Link>
</Compile> </Compile>
<Compile Include="..\Dapper.EntityFramework NET45\SqlGeographyHandler.cs">
<Link>SqlGeographyHandler.cs</Link>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SqlServerTypes\Loader.cs" /> <Compile Include="SqlServerTypes\Loader.cs" />
</ItemGroup> </ItemGroup>
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
<Compile Include="DbGeographyHandler.cs" /> <Compile Include="DbGeographyHandler.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Handlers.cs" /> <Compile Include="Handlers.cs" />
<Compile Include="SqlGeographyHandler.cs" />
<Compile Include="SqlServerTypes\Loader.cs" /> <Compile Include="SqlServerTypes\Loader.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
......
namespace Dapper.EntityFramework using Microsoft.SqlServer.Types;
namespace Dapper.EntityFramework
{ {
/// <summary> /// <summary>
/// Acts on behalf of all type-handlers in this package /// Acts on behalf of all type-handlers in this package
...@@ -11,6 +13,7 @@ public static class Handlers ...@@ -11,6 +13,7 @@ public static class Handlers
public static void Register() public static void Register()
{ {
SqlMapper.AddTypeHandler(DbGeographyHandler.Default); SqlMapper.AddTypeHandler(DbGeographyHandler.Default);
SqlMapper.AddTypeHandler(SqlGeographyHandler.Default);
} }
} }
} }
using Microsoft.SqlServer.Types;
using System;
using System.Data;
using System.Data.Entity.Spatial;
using System.Data.SqlClient;
namespace Dapper.EntityFramework
{
/// <summary>
/// Type-handler for the DbGeography spatial type
/// </summary>
public class SqlGeographyHandler : Dapper.SqlMapper.TypeHandler<SqlGeography>
{
/// <summary>
/// Create a new handler instance
/// </summary>
protected SqlGeographyHandler() { }
/// <summary>
/// Default handler instance
/// </summary>
public static readonly SqlGeographyHandler Default = new SqlGeographyHandler();
/// <summary>
/// Assign the value of a parameter before a command executes
/// </summary>
/// <param name="parameter">The parameter to configure</param>
/// <param name="value">Parameter value</param>
public override void SetValue(IDbDataParameter parameter, SqlGeography value)
{
parameter.Value = ((object)value) ?? DBNull.Value;
if (parameter is SqlParameter)
{
((SqlParameter)parameter).UdtTypeName = "GEOGRAPHY";
}
}
/// <summary>
/// Parse a database value back to a typed value
/// </summary>
/// <param name="value">The value from the database</param>
/// <returns>The typed value</returns>
public override SqlGeography Parse(object value)
{
return value as SqlGeography;
}
}
}
...@@ -68,6 +68,10 @@ ...@@ -68,6 +68,10 @@
<Reference Include="LinFu.DynamicProxy"> <Reference Include="LinFu.DynamicProxy">
<HintPath>NHibernate\LinFu.DynamicProxy.dll</HintPath> <HintPath>NHibernate\LinFu.DynamicProxy.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.SqlServer.Types, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\packages\Microsoft.SqlServer.Types.11.0.1\lib\net20\Microsoft.SqlServer.Types.dll</HintPath>
</Reference>
<Reference Include="Mono.Security"> <Reference Include="Mono.Security">
<HintPath>..\packages\Npgsql.2.0.11\lib\Net40\Mono.Security.dll</HintPath> <HintPath>..\packages\Npgsql.2.0.11\lib\Net40\Mono.Security.dll</HintPath>
</Reference> </Reference>
...@@ -161,6 +165,7 @@ ...@@ -161,6 +165,7 @@
<DesignTimeSharedInput>True</DesignTimeSharedInput> <DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon> <DependentUpon>Settings.settings</DependentUpon>
</Compile> </Compile>
<Compile Include="SqlServerTypes\Loader.cs" />
<Compile Include="SubSonic\ActiveRecord.cs"> <Compile Include="SubSonic\ActiveRecord.cs">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
...@@ -224,6 +229,22 @@ ...@@ -224,6 +229,22 @@
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="..\packages\Microsoft.SqlServer.Types.11.0.1\nativeBinaries\x64\msvcr100.dll">
<Link>SqlServerTypes\x64\msvcr100.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\packages\Microsoft.SqlServer.Types.11.0.1\nativeBinaries\x64\SqlServerSpatial110.dll">
<Link>SqlServerTypes\x64\SqlServerSpatial110.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\packages\Microsoft.SqlServer.Types.11.0.1\nativeBinaries\x86\msvcr100.dll">
<Link>SqlServerTypes\x86\msvcr100.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\packages\Microsoft.SqlServer.Types.11.0.1\nativeBinaries\x86\SqlServerSpatial110.dll">
<Link>SqlServerTypes\x86\SqlServerSpatial110.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="NHibernate\hibernate.cfg.xml" /> <Content Include="NHibernate\hibernate.cfg.xml" />
<Content Include="NHibernate\Post.hbm.xml" /> <Content Include="NHibernate\Post.hbm.xml" />
<Content Include="OrmLite\ServiceStack.Common.dll" /> <Content Include="OrmLite\ServiceStack.Common.dll" />
...@@ -234,6 +255,7 @@ ...@@ -234,6 +255,7 @@
<Content Include="Soma\Soma.Core.dll" /> <Content Include="Soma\Soma.Core.dll" />
<Content Include="Soma\Soma.Core.IT.MsSql.dll" /> <Content Include="Soma\Soma.Core.IT.MsSql.dll" />
<Content Include="Soma\Soma.Core.IT.MsSqlCe.dll" /> <Content Include="Soma\Soma.Core.IT.MsSqlCe.dll" />
<Content Include="SqlServerTypes\readme.htm" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="bltoolkit\" /> <Folder Include="bltoolkit\" />
......
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace SqlServerTypes
{
/// <summary>
/// Utility methods related to CLR Types for SQL Server
/// </summary>
internal class Utilities
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr LoadLibrary(string libname);
/// <summary>
/// Loads the required native assemblies for the current architecture (x86 or x64)
/// </summary>
/// <param name="rootApplicationPath">
/// Root path of the current application. Use Server.MapPath(".") for ASP.NET applications
/// and AppDomain.CurrentDomain.BaseDirectory for desktop applications.
/// </param>
public static void LoadNativeAssemblies(string rootApplicationPath)
{
var nativeBinaryPath = IntPtr.Size > 4
? Path.Combine(rootApplicationPath, @"SqlServerTypes\x64\")
: Path.Combine(rootApplicationPath, @"SqlServerTypes\x86\");
LoadNativeAssembly(nativeBinaryPath, "msvcr100.dll");
LoadNativeAssembly(nativeBinaryPath, "SqlServerSpatial110.dll");
}
private static void LoadNativeAssembly(string nativeBinaryPath, string assemblyName)
{
var path = Path.Combine(nativeBinaryPath, assemblyName);
var ptr = LoadLibrary(path);
if (ptr == IntPtr.Zero)
{
throw new Exception(string.Format(
"Error loading {0} (ErrorCode: {1})",
assemblyName,
Marshal.GetLastWin32Error()));
}
}
}
}
\ No newline at end of file
<html lang="en-US">
<head>
<meta charset="utf-8" />
<title>Microsoft.SqlServer.Types</title>
<style>
body {
background: #fff;
color: #505050;
margin: 20px;
}
#main {
background: #efefef;
padding: 5px 30px;
}
</style>
</head>
<body>
<div id="main">
<h1>Action required to load native assemblies</h1>
<p>
To deploy an application that uses spatial data types to a machine that does not have 'System CLR Types for SQL Server' installed you also need to deploy the native assembly SqlServerSpatial110.dll. Both x86 (32 bit) and x64 (64 bit) versions of this assembly have been added to your project under the SqlServerTypes\x86 and SqlServerTypes\x64 subdirectories. The native assembly msvcr100.dll is also included in case the C++ runtime is not installed.
</p>
<p>
You need to add code to load the correct one of these assemblies at runtime (depending on the current architecture).
</p>
<h2>ASP.NET applications</h2>
<p>
For ASP.NET applications, add the following line of code to the Application_Start method in Global.asax.cs:
<pre> SqlServerTypes.Utilities.LoadNativeAssemblies(Server.MapPath("~/bin"));</pre>
</p>
<h2>Desktop applications</h2>
<p>
For desktop applications, add the following line of code to run before any spatial operations are performed:
<pre> SqlServerTypes.Utilities.LoadNativeAssemblies(AppDomain.CurrentDomain.BaseDirectory);</pre>
</p>
</div>
</body>
</html>
\ No newline at end of file
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
using System.Globalization; using System.Globalization;
using System.Threading; using System.Threading;
using System.Data.Entity.Spatial; using System.Data.Entity.Spatial;
using Microsoft.SqlServer.Types;
using System.Data.SqlTypes;
#if POSTGRESQL #if POSTGRESQL
using Npgsql; using Npgsql;
#endif #endif
...@@ -2985,6 +2987,11 @@ class HazGeo ...@@ -2985,6 +2987,11 @@ class HazGeo
public int Id { get; set; } public int Id { get; set; }
public DbGeography Geo { get; set; } public DbGeography Geo { get; set; }
} }
class HazSqlGeo
{
public int Id { get; set; }
public SqlGeography Geo { get; set; }
}
public void DBGeography_SO24405645_SO24402424() public void DBGeography_SO24405645_SO24402424()
{ {
Dapper.EntityFramework.Handlers.Register(); Dapper.EntityFramework.Handlers.Register();
...@@ -3003,6 +3010,24 @@ public void DBGeography_SO24405645_SO24402424() ...@@ -3003,6 +3010,24 @@ public void DBGeography_SO24405645_SO24402424()
row.Geo.IsNotNull(); row.Geo.IsNotNull();
} }
public void SqlGeography_SO25538154()
{
Dapper.EntityFramework.Handlers.Register();
connection.Execute("create table #SqlGeo (id int, geo geography)");
var obj = new HazSqlGeo
{
Id = 1,
Geo = SqlGeography.STLineFromText(new SqlChars(new SqlString("LINESTRING(-122.360 47.656, -122.343 47.656 )")), 4326)
};
connection.Execute("insert #SqlGeo(id, geo) values (@Id, @Geo)", obj);
var row = connection.Query<HazGeo>("select * from #SqlGeo where id=1").SingleOrDefault();
row.IsNotNull();
row.Id.IsEqualTo(1);
row.Geo.IsNotNull();
}
public void TypeBasedViaDynamic() public void TypeBasedViaDynamic()
{ {
Type type = GetSomeType(); Type type = GetSomeType();
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<packages> <packages>
<package id="EntityFramework" version="6.1.0" targetFramework="net45" /> <package id="EntityFramework" version="6.1.0" targetFramework="net45" />
<package id="FSPowerPack.Community" version="2.0.0.0" /> <package id="FSPowerPack.Community" version="2.0.0.0" />
<package id="Microsoft.SqlServer.Types" version="11.0.1" targetFramework="net45" />
<package id="Npgsql" version="2.0.11" /> <package id="Npgsql" version="2.0.11" />
<package id="SqlServerCompact" version="4.0.8482.1" /> <package id="SqlServerCompact" version="4.0.8482.1" />
</packages> </packages>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment