Exemple #1
0
        static SqlTypes()
        {
            // find the latest version of Microsoft.SqlServer.Types assembly that contains Sql spatial types
            var preferredSqlTypesAssemblies = new[]
            {
                "Microsoft.SqlServer.Types, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91",
                "Microsoft.SqlServer.Types, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91",
            };

            Assembly sqlTypesAssembly = null;

            foreach (string assemblyFullName in preferredSqlTypesAssemblies)
            {
                AssemblyName asmName = new AssemblyName(assemblyFullName);
                try
                {
                    sqlTypesAssembly = Assembly.Load(asmName);
                    break;
                }
                catch (FileNotFoundException)
                {
                }
                catch (FileLoadException)
                {
                }
            }

            if (sqlTypesAssembly == null)
            {
                throw new InvalidOperationException("Microsoft.SqlServer.Types assembly not found");
            }

            SqlGeographyType = sqlTypesAssembly.GetType("Microsoft.SqlServer.Types.SqlGeography", throwOnError: true);
            SqlGeometryType  = sqlTypesAssembly.GetType("Microsoft.SqlServer.Types.SqlGeometry", throwOnError: true);

            SqlCharsType  = SqlGeometryType.GetMethod("STAsText", BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null).ReturnType;
            SqlStringType = SqlCharsType.Assembly.GetType("System.Data.SqlTypes.SqlString", throwOnError: true);
            SqlBytesType  = SqlCharsType.Assembly.GetType("System.Data.SqlTypes.SqlBytes", throwOnError: true);
            SqlXmlType    = SqlCharsType.Assembly.GetType("System.Data.SqlTypes.SqlXml", throwOnError: true);
        }
Exemple #2
0
        public SqlTypesAssembly(Assembly sqlSpatialAssembly)
        {
            // Retrieve SQL Server spatial types and static constructor methods
            var sqlGeog = sqlSpatialAssembly.GetType("Microsoft.SqlServer.Types.SqlGeography", throwOnError: true);
            var sqlGeom = sqlSpatialAssembly.GetType("Microsoft.SqlServer.Types.SqlGeometry", throwOnError: true);

            Debug.Assert(sqlGeog != null, "SqlGeography type was not properly retrieved?");
            Debug.Assert(sqlGeom != null, "SqlGeometry type was not properly retrieved?");

            SqlGeographyType             = sqlGeog;
            sqlGeographyFromWKTString    = CreateStaticConstructorDelegate <string>(sqlGeog, "STGeomFromText");
            sqlGeographyFromWKBByteArray = CreateStaticConstructorDelegate <byte[]>(sqlGeog, "STGeomFromWKB");
            sqlGeographyFromGMLReader    = CreateStaticConstructorDelegate <XmlReader>(sqlGeog, "GeomFromGml");

            SqlGeometryType             = sqlGeom;
            sqlGeometryFromWKTString    = CreateStaticConstructorDelegate <string>(sqlGeom, "STGeomFromText");
            sqlGeometryFromWKBByteArray = CreateStaticConstructorDelegate <byte[]>(sqlGeom, "STGeomFromWKB");
            sqlGeometryFromGMLReader    = CreateStaticConstructorDelegate <XmlReader>(sqlGeom, "GeomFromGml");

            // Retrieve SQL Server specific primitive types
            var asTextMethod = SqlGeometryType.GetMethod(
                "STAsText", BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null);

            SqlCharsType   = asTextMethod.ReturnType;
            SqlStringType  = SqlCharsType.Assembly.GetType("System.Data.SqlTypes.SqlString", throwOnError: true);
            SqlBooleanType = SqlCharsType.Assembly.GetType("System.Data.SqlTypes.SqlBoolean", throwOnError: true);
            SqlBytesType   = SqlCharsType.Assembly.GetType("System.Data.SqlTypes.SqlBytes", throwOnError: true);
            SqlDoubleType  = SqlCharsType.Assembly.GetType("System.Data.SqlTypes.SqlDouble", throwOnError: true);
            SqlInt32Type   = SqlCharsType.Assembly.GetType("System.Data.SqlTypes.SqlInt32", throwOnError: true);
            SqlXmlType     = SqlCharsType.Assembly.GetType("System.Data.SqlTypes.SqlXml", throwOnError: true);

            // Create type conversion delegates to SQL Server types
            sqlBytesFromByteArray =
                Expressions.Lambda <byte[], object>("binaryValue", bytesVal => BuildConvertToSqlBytes(bytesVal, SqlBytesType)).Compile();
            sqlStringFromString =
                Expressions.Lambda <string, object>("stringValue", stringVal => BuildConvertToSqlString(stringVal, SqlStringType)).Compile();
            sqlCharsFromString =
                Expressions.Lambda <string, object>("stringValue", stringVal => BuildConvertToSqlChars(stringVal, SqlCharsType)).Compile();
            sqlXmlFromXmlReader =
                Expressions.Lambda <XmlReader, object>("readerVaue", readerVal => BuildConvertToSqlXml(readerVal, SqlXmlType)).Compile();

            // Create type conversion delegates from SQL Server types; all arguments are typed as 'object' and require Expression.Convert before use of members of the SQL Server type.

            // Explicit cast from SqlBoolean to bool
            sqlBooleanToBoolean =
                Expressions.Lambda <object, bool>("sqlBooleanValue", sqlBoolVal => sqlBoolVal.ConvertTo(SqlBooleanType).ConvertTo <bool>()).
                Compile();

            // Explicit cast from SqlBoolean to bool? for non-Null values; otherwise null
            sqlBooleanToNullableBoolean = Expressions.Lambda <object, bool?>(
                "sqlBooleanValue", sqlBoolVal =>
                sqlBoolVal.ConvertTo(SqlBooleanType).Property <bool>("IsNull")
                .IfTrueThen(Expressions.Null <bool?>())
                .Else(sqlBoolVal.ConvertTo(SqlBooleanType).ConvertTo <bool>().ConvertTo <bool?>())).Compile();

            // SqlBytes has instance byte[] property 'Value'
            sqlBytesToByteArray =
                Expressions.Lambda <object, byte[]>(
                    "sqlBytesValue", sqlBytesVal => sqlBytesVal.ConvertTo(SqlBytesType).Property <byte[]>("Value")).Compile();

            // SqlChars -> SqlString, SqlString has instance string property 'Value'
            sqlCharsToString =
                Expressions.Lambda <object, string>(
                    "sqlCharsValue", sqlCharsVal => sqlCharsVal.ConvertTo(SqlCharsType).Call("ToSqlString").Property <string>("Value")).
                Compile();

            // Explicit cast from SqlString to string
            sqlStringToString =
                Expressions.Lambda <object, string>(
                    "sqlStringValue", sqlStringVal => sqlStringVal.ConvertTo(SqlStringType).Property <string>("Value")).Compile();

            // Explicit cast from SqlDouble to double
            sqlDoubleToDouble =
                Expressions.Lambda <object, double>(
                    "sqlDoubleValue", sqlDoubleVal => sqlDoubleVal.ConvertTo(SqlDoubleType).ConvertTo <double>()).Compile();

            // Explicit cast from SqlDouble to double? for non-Null values; otherwise null
            sqlDoubleToNullableDouble = Expressions.Lambda <object, double?>(
                "sqlDoubleValue", sqlDoubleVal =>
                sqlDoubleVal.ConvertTo(SqlDoubleType).Property <bool>("IsNull")
                .IfTrueThen(Expressions.Null <double?>())
                .Else(sqlDoubleVal.ConvertTo(SqlDoubleType).ConvertTo <double>().ConvertTo <double?>()))
                                        .Compile();

            // Explicit cast from SqlInt32 to int
            sqlInt32ToInt =
                Expressions.Lambda <object, int>("sqlInt32Value", sqlInt32Val => sqlInt32Val.ConvertTo(SqlInt32Type).ConvertTo <int>()).
                Compile();

            // Explicit cast from SqlInt32 to int? for non-Null values; otherwise null
            sqlInt32ToNullableInt = Expressions.Lambda <object, int?>(
                "sqlInt32Value", sqlInt32Val =>
                sqlInt32Val.ConvertTo(SqlInt32Type).Property <bool>("IsNull")
                .IfTrueThen(Expressions.Null <int?>())
                .Else(sqlInt32Val.ConvertTo(SqlInt32Type).ConvertTo <int>().ConvertTo <int?>())).Compile();

            // SqlXml has instance string property 'Value'
            sqlXmlToString =
                Expressions.Lambda <object, string>("sqlXmlValue", sqlXmlVal => sqlXmlVal.ConvertTo(SqlXmlType).Property <string>("Value")).
                Compile();

            isSqlGeographyNull =
                Expressions.Lambda <object, bool>(
                    "sqlGeographyValue", sqlGeographyValue => sqlGeographyValue.ConvertTo(SqlGeographyType).Property <bool>("IsNull")).
                Compile();
            isSqlGeometryNull =
                Expressions.Lambda <object, bool>(
                    "sqlGeometryValue", sqlGeometryValue => sqlGeometryValue.ConvertTo(SqlGeometryType).Property <bool>("IsNull")).Compile();

            geographyAsTextZMAsSqlChars =
                Expressions.Lambda <object, object>(
                    "sqlGeographyValue", sqlGeographyValue => sqlGeographyValue.ConvertTo(SqlGeographyType).Call("AsTextZM")).Compile();
            geometryAsTextZMAsSqlChars =
                Expressions.Lambda <object, object>(
                    "sqlGeometryValue", sqlGeometryValue => sqlGeometryValue.ConvertTo(SqlGeometryType).Call("AsTextZM")).Compile();
        }