2015-03-11 2 views
8

Когда в Linq To SQL Я использую определенные пользователем функции, как этотКак я могу заставить длину VARCHAR в Linq To SQL

[Function(Name = "udf_find_a", IsComposable = true)] 
public IQueryable<A> FindA([Parameter(DbType = "varchar(100)")] string keywords) 
{ 
    return CreateMethodCallQuery<A>(this, ((MethodInfo) (MethodBase.GetCurrentMethod())), keywords); 
} 

в результате запроса всегда содержит VARCHAR (8000) в качестве параметра типа.

Поэтому я должен изменить тип параметра функции, чтобы избежать ошибки SQL Server.

Могу ли я заставить Linq To SQL игнорировать длину, которую я передаю?

P.S. Существует такая же проблема с nvarchar (4000).

+0

Вы видите какую-либо разницу, если вы укажете имя параметра в функции (т. е. 'FindA [Параметр (Name = @" keywords ", DbType = @" varchar (100) ")] строковые слова)')? –

ответ

1

Просматривая декомпилируемую коду не очень похоже, что это обращает внимание на этот атрибут при составлении запроса, и я не вижу путь, который позволил бы установить его

Это выглядит файл который определяет размер параметра использовать

https://github.com/Microsoft/referencesource/blob/master/System.Data.Linq/SqlClient/SqlTypeSystemProvider.cs

Эта часть внутри InitializeParameter инициализирует размера

int? determinedSize = DetermineParameterSize(sqlType, parameter); 
if (determinedSize.HasValue) { 
     parameter.Size = determinedSize.Value; 
} 

Затем следуя выполнить путь только установить 8000 для типа VARCHAR и 4000 для nvarchars и на самом деле не всегда смотреть на этот атрибут

internal virtual int? DetermineParameterSize(SqlType declaredType, DbParameter parameter) { 
     // Output parameters and input-parameters of a fixed-size should be specifically set if value fits. 
     bool isInputParameter = parameter.Direction == ParameterDirection.Input; 
     if (!isInputParameter || declaredType.IsFixedSize) { 
      if (declaredType.Size.HasValue && parameter.Size <= declaredType.Size || declaredType.IsLargeType) { 
       return declaredType.Size.Value; 
      } 
     } 

     // Preserve existing provider & server-driven behaviour for all other cases. 
     return null; 
    } 

    protected int? GetLargestDeclarableSize(SqlType declaredType) { 
      switch (declaredType.SqlDbType) { 
      case SqlDbType.Image: 
      case SqlDbType.Binary: 
      case SqlDbType.VarChar: 
       return 8000; 
      case SqlDbType.NVarChar: 
       return 4000; 
      default: 
       return null; 
     } 
    } 

    internal virtual int? DetermineParameterSize(SqlType declaredType, DbParameter parameter) { 
    // Output parameters and input-parameters of a fixed-size should be specifically set if value fits. 
    bool isInputParameter = parameter.Direction == ParameterDirection.Input; 
    if (!isInputParameter || declaredType.IsFixedSize) { 
     if (declaredType.Size.HasValue && parameter.Size <= declaredType.Size || declaredType.IsLargeType) { 
      return declaredType.Size.Value; 
     } 
    } 

    // Preserve existing provider & server-driven behaviour for all other cases. 
    return null; 
} 

это заявление

if (!isInputParameter || declaredType.IsFixedSize) 

IsFixedSize возвращает ложь для VARCHAR и NVARCHAR, которые вы можете увидеть здесь

internal override bool IsFixedSize { 
    get { 
     switch (this.sqlDbType) { 
      case SqlDbType.NText: 
      case SqlDbType.Text: 
      case SqlDbType.NVarChar: 
      case SqlDbType.VarChar: 
      case SqlDbType.Image: 
      case SqlDbType.VarBinary: 
      case SqlDbType.Xml: 
       return false; 
      default: 
       return true; 
     } 
    } 
} 

источника я вышел через код во время выполнения функции, а также следить за его выполнение годовым th ... Также не кажется, что есть какие-либо полезные перемычки для изменения перед выполнением. SqlProvider не имеет ничего полезного в том, чтобы переопределить или подключить либо ....

Смежные вопросы