Commit 3691fe13 authored by Marc Gravell's avatar Marc Gravell

allow null arrays on suitable RDBMS

parent bff05e72
...@@ -2394,96 +2394,92 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj ...@@ -2394,96 +2394,92 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
// initially we tried TVP, however it performs quite poorly. // initially we tried TVP, however it performs quite poorly.
// keep in mind SQL support up to 2000 params easily in sp_executesql, needing more is rare // keep in mind SQL support up to 2000 params easily in sp_executesql, needing more is rare
var list = value as IEnumerable; if (FeatureSupport.Get(command.Connection).Arrays)
var count = 0;
if (list != null)
{ {
if (FeatureSupport.Get(command.Connection).Arrays) var arrayParm = command.CreateParameter();
{ arrayParm.Value = value ?? DBNull.Value;
var arrayParm = command.CreateParameter(); arrayParm.ParameterName = namePrefix;
arrayParm.Value = list; command.Parameters.Add(arrayParm);
arrayParm.ParameterName = namePrefix; }
command.Parameters.Add(arrayParm); else
} {
else var list = value as IEnumerable;
var count = 0;
bool isString = value is IEnumerable<string>;
bool isDbString = value is IEnumerable<DbString>;
foreach (var item in list)
{ {
bool isString = value is IEnumerable<string>; count++;
bool isDbString = value is IEnumerable<DbString>; var listParam = command.CreateParameter();
foreach (var item in list) listParam.ParameterName = namePrefix + count;
listParam.Value = item ?? DBNull.Value;
if (isString)
{ {
count++; listParam.Size = 4000;
var listParam = command.CreateParameter(); if (item != null && ((string)item).Length > 4000)
listParam.ParameterName = namePrefix + count;
listParam.Value = item ?? DBNull.Value;
if (isString)
{ {
listParam.Size = 4000; listParam.Size = -1;
if (item != null && ((string)item).Length > 4000)
{
listParam.Size = -1;
}
} }
if (isDbString && item as DbString != null) }
if (isDbString && item as DbString != null)
{
var str = item as DbString;
str.AddParameter(command, listParam.ParameterName);
}
else
{
command.Parameters.Add(listParam);
}
}
var regexIncludingUnknown = @"([?@:]" + Regex.Escape(namePrefix) + @")(\s+(?i)unknown(?-i))?";
if (count == 0)
{
command.CommandText = Regex.Replace(command.CommandText, regexIncludingUnknown, match =>
{
var variableName = match.Groups[1].Value;
if (match.Groups[2].Success)
{ {
var str = item as DbString; // looks like an optimize hint; leave it alone!
str.AddParameter(command, listParam.ParameterName); return match.Value;
} }
else else
{ {
command.Parameters.Add(listParam); return "(SELECT " + variableName + " WHERE 1 = 0)";
} }
} });
var dummyParam = command.CreateParameter();
var regexIncludingUnknown = @"([?@:]" + Regex.Escape(namePrefix) + @")(\s+(?i)unknown(?-i))?"; dummyParam.ParameterName = namePrefix;
if (count == 0) dummyParam.Value = DBNull.Value;
command.Parameters.Add(dummyParam);
}
else
{
command.CommandText = Regex.Replace(command.CommandText, regexIncludingUnknown, match =>
{ {
command.CommandText = Regex.Replace(command.CommandText, regexIncludingUnknown, match => var variableName = match.Groups[1].Value;
if (match.Groups[2].Success)
{ {
var variableName = match.Groups[1].Value; // looks like an optimize hint; expand it
if (match.Groups[2].Success) var suffix = match.Groups[2].Value;
{
// looks like an optimize hint; leave it alone! var sb = new StringBuilder(variableName).Append(1).Append(suffix);
return match.Value; for (int i = 2; i <= count; i++)
}
else
{ {
return "(SELECT " + variableName + " WHERE 1 = 0)"; sb.Append(',').Append(variableName).Append(i).Append(suffix);
} }
}); return sb.ToString();
var dummyParam = command.CreateParameter(); }
dummyParam.ParameterName = namePrefix; else
dummyParam.Value = DBNull.Value;
command.Parameters.Add(dummyParam);
}
else
{
command.CommandText = Regex.Replace(command.CommandText, regexIncludingUnknown, match =>
{ {
var variableName = match.Groups[1].Value; var sb = new StringBuilder("(").Append(variableName).Append(1);
if (match.Groups[2].Success) for (int i = 2; i <= count; i++)
{ {
// looks like an optimize hint; expand it sb.Append(',').Append(variableName).Append(i);
var suffix = match.Groups[2].Value;
var sb = new StringBuilder(variableName).Append(1).Append(suffix);
for (int i = 2; i <= count; i++)
{
sb.Append(',').Append(variableName).Append(i).Append(suffix);
}
return sb.ToString();
} }
else return sb.Append(')').ToString();
{ }
var sb = new StringBuilder("(").Append(variableName).Append(1); });
for (int i = 2; i <= count; i++)
{
sb.Append(',').Append(variableName).Append(i);
}
return sb.Append(')').ToString();
}
});
}
} }
} }
......
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