Skip to content

Commit

Permalink
Update UDT spatial serialization to use WKT
Browse files Browse the repository at this point in the history
  • Loading branch information
ajcvickers committed Oct 12, 2018
1 parent 5b7e955 commit 31e0e41
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 36 deletions.
32 changes: 19 additions & 13 deletions src/EFCore.SqlServer/Storage/Internal/SqlServerUdtTypeMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,18 +151,24 @@ public static SqlServerUdtTypeMapping CreateSqlSpatialMapping(Type udtType, stri
=> new SqlServerUdtTypeMapping(
udtType,
storeName,
v => Expression.Call(
v.GetType().GetMethod("Deserialize"),
Expression.New(
typeof(SqlBytes).GetConstructor(
new[] { typeof(byte[]) }),
Expression.NewArrayInit(
typeof(byte),
((SqlBytes)v.GetType()
.GetMethod("Serialize")
.Invoke(v, new object[0]))
.Value
.Select(b => (Expression)Expression.Constant(b, typeof(byte)))
.ToArray()))));
v =>
{
var spatialType = v.GetType();
var noParams = new object[0];
var wkt = ((SqlChars)spatialType.GetMethod("AsTextZM").Invoke(v, noParams)).ToSqlString().ToString();
var srid = ((SqlInt32)spatialType.GetMethod("get_STSrid").Invoke(v, noParams)).Value;
return Expression.Call(
spatialType.GetMethod("STGeomFromText"),
Expression.New(
typeof(SqlChars).GetConstructor(
new[] { typeof(SqlString) }),
Expression.New(
typeof(SqlString).GetConstructor(
new[] { typeof(string) }),
Expression.Constant(wkt, typeof(string)))),
Expression.Constant(srid, typeof(int)));
});
}
}
56 changes: 33 additions & 23 deletions test/EFCore.Design.Tests/Design/Internal/CSharpHelperTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -547,10 +547,8 @@ public virtual void Can_generate_SqlGeometry_literal()
.LiteralGenerator));

Assert.Equal(
"Microsoft.SqlServer.Types.FakeSqlGeometry.Deserialize(new System.Data.SqlTypes.SqlBytes(new byte[] { 0, 0, 0, 0, 1, 12, 0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 0, 64 }))",
new CSharpHelper(typeMapping).UnknownLiteral(
FakeSqlGeometry.Deserialize(
new SqlBytes(new byte[] { 0, 0, 0, 0, 1, 12, 0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 0, 64 }))));
"Microsoft.SqlServer.Types.FakeSqlGeometry.STGeomFromText(new System.Data.SqlTypes.SqlChars(new System.Data.SqlTypes.SqlString(\"POINT (1 2)\")), 0)",
new CSharpHelper(typeMapping).UnknownLiteral(new FakeSqlGeometry("POINT (1 2)", 0)));
}

[Fact]
Expand All @@ -564,10 +562,8 @@ public virtual void Can_generate_SqlGeography_literal()
.LiteralGenerator));

Assert.Equal(
"Microsoft.SqlServer.Types.FakeSqlGeography.Deserialize(new System.Data.SqlTypes.SqlBytes(new byte[] { 230, 16, 0, 0, 1, 12, 0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 0, 64 }))",
new CSharpHelper(typeMapping).UnknownLiteral(
FakeSqlGeography.Deserialize(
new SqlBytes(new byte[] { 230, 16, 0, 0, 1, 12, 0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 0, 64 }))));
"Microsoft.SqlServer.Types.FakeSqlGeography.STGeomFromText(new System.Data.SqlTypes.SqlChars(new System.Data.SqlTypes.SqlString(\"POINT (1 2)\")), 4326)",
new CSharpHelper(typeMapping).UnknownLiteral(new FakeSqlGeography("POINT (1 2)", 4326)));
}

private IRelationalTypeMappingSource TypeMappingSource { get; } = CreateTypeMappingSource();
Expand Down Expand Up @@ -704,30 +700,44 @@ public override string ToString()
// Has the same shape as Microsoft.SqlServer.Types.SqlGeometry for testing code gen
public class FakeSqlGeometry
{
private readonly SqlBytes _value;
private readonly string _text;
private readonly int _srid;

private FakeSqlGeometry(SqlBytes value)
=> _value = value;
public FakeSqlGeometry(string text, int srid)
{
_text = text;
_srid = srid;
}

public SqlChars AsTextZM() => new SqlChars(_text);

public static FakeSqlGeometry Deserialize(SqlBytes bytes)
=> new FakeSqlGeometry(bytes);
public SqlInt32 STSrid => _srid;

public SqlBytes Serialize()
=> _value;
public static FakeSqlGeometry STGeomFromText(SqlChars geometryTaggedText, int srid)
{
return new FakeSqlGeometry(geometryTaggedText.ToSqlString().ToString(), srid);
}
}

// Has the same shape as Microsoft.SqlServer.Types.SqlGeometry for testing code gen
// Has the same shape as Microsoft.SqlServer.Types.SqlGeography for testing code gen
public class FakeSqlGeography
{
private readonly SqlBytes _value;
private readonly string _text;
private readonly int _srid;

private FakeSqlGeography(SqlBytes value)
=> _value = value;
public FakeSqlGeography(string text, int srid)
{
_text = text;
_srid = srid;
}

public static FakeSqlGeography Deserialize(SqlBytes bytes)
=> new FakeSqlGeography(bytes);
public SqlChars AsTextZM() => new SqlChars(_text);

public SqlBytes Serialize()
=> _value;
public SqlInt32 STSrid => _srid;

public static FakeSqlGeography STGeomFromText(SqlChars geometryTaggedText, int srid)
{
return new FakeSqlGeography(geometryTaggedText.ToSqlString().ToString(), srid);
}
}
}

0 comments on commit 31e0e41

Please sign in to comment.