Мне нужно поддерживать тип ntext
SQL Server CE в Dapper. Здесь есть ветка с описанием проблемы: https://code.google.com/p/dapper-dot-net/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Summary&groupby=&sort=&id=110
Я попытался изменить Dapper, чтобы использовать решение, аналогичное подходу, используемому в PetaPoco: https://github.com/cyotek/PetaPoco/commit/ea13add473be3899ebb73b463d2aff98f8d6d06e
Изучив исходный код Dapper, я решил, что хороший способ попытаться это сделать — изменить класс DbString
. Я изменил метод AddParameter(IDbCommand command, string name)
(начиная со строки 3120) на следующее:
public void AddParameter(IDbCommand command, string name)
{
if (IsFixedLength && Length == -1)
{
throw new InvalidOperationException("If specifying IsFixedLength, a Length must also be specified");
}
var param = command.CreateParameter();
param.ParameterName = name;
param.Value = (object)Value ?? DBNull.Value;
if (Length == -1 && Value != null && Value.Length <= 4000)
{
param.Size = 4000;
}
else
{
param.Size = Length;
}
param.DbType = IsAnsi ? (IsFixedLength ? DbType.AnsiStringFixedLength : DbType.AnsiString) : (IsFixedLength ? DbType.StringFixedLength : DbType.String);
if (param.Value != null)
{
if (param.Value.ToString().Length + 1 > 4000 && param.GetType().Name == "SqlCeParameter")
{
param.GetType().GetProperty("SqlDbType").SetValue(param, System.Data.SqlDbType.NText, null);
}
}
command.Parameters.Add(param);
}
Мое редактирование — это часть внизу, которая проверяет тип и пытается изменить его на ntext
. Однако, когда я запускаю этот код, происходит сбой IIS Express, и asp.net не дает мне никакой полезной информации об отладке. Я попытался запустить его в отладчике, и я получаю ошибку, связанную с повреждением кучи.
Я на неправильном пути здесь? Есть ли лучший способ попробовать что-то подобное в Dapper? Или это что-то, что просто не будет работать из-за того, как генерируется кеш и/или IL? Я надеялся создать для него запрос на вытягивание, если я смогу заставить его работать, но я отказываюсь.
Обновление - я нашел одно потенциальное решение. Я добавил некоторый код в метод AddParameters(IDbCommand command, SqlMapper.Identity identity)
класса DynamicParameters
. Последние строки метода теперь гласят:
if (s != null)
{
if (s.Length + 1 > 4000 && p.GetType().Name == "SqlCeParameter")
{
p.GetType().GetProperty("SqlDbType").SetValue(p, SqlDbType.NText, null);
p.Size = s.Length;
}
}
if (add)
{
command.Parameters.Add(p);
}
param.AttachedParam = p;
Чтобы использовать это решение, я должен добавить свои параметры как DynamicParameters. Так что это работает, но не самым полезным образом. Я все еще ищу лучшее решение.
Это то, что разработчики Dapper рассмотрят как патч, если я создам запрос на включение?