Возникла необходимость использовать типы из Microsoft.SqlServer.Types.* (SqlHierarchyId, SqlGeometry, SqlGeography).
ADO.NET работает с этими типами как с UDT, в связи с чем пришлось немного допилить BLT.
Предлагается следующее:
1) DataProviderBase добавить:
public Func<object, string> UdtTypeNameFromValueResolver = o =>
{
if (o == null)
return "";
var name = o.GetType().Name;
switch (name)
{
case "SqlGeography":
return "Geography";
case "SqlGeometry":
return "Geometry";
case "SqlHierarchyId":
return "hierarchyid";
default:
return name;
}
};
Изменить:
public virtual void SetParameterValue(IDbDataParameter parameter, object value)
{
if (value is System.Data.Linq.Binary)
{
var arr = ((System.Data.Linq.Binary)value).ToArray();
parameter.Value = arr;
parameter.DbType = DbType.Binary;
parameter.Size = arr.Length;
}
else
{
parameter.Value = value;
if (parameter.DbType==DbType.Object) // ! Добавлено !
{
SetUserDefinedType(parameter, UdtTypeNameFromValueResolver(value));
}
}
}
2) В SqlDataProviderBase изменить:
public override void SetUserDefinedType(IDbDataParameter parameter, string typeName)
{
if (!(parameter is SqlParameter))
throw new ArgumentException("SqlParameter expected.", "parameter");
var sqlParameter = (SqlParameter)parameter;
if (SqlDbType.Structured == sqlParameter.SqlDbType)
sqlParameter.TypeName = typeName;
else
sqlParameter.UdtTypeName = typeName;
}
Если кто использовал другие приемы для работы с UDT — прошу поделится