在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 :(得分:1)
查看反编译代码,在编写查询时看起来并不真正关注该属性,而且我真的没有看到可以让你设置它的路径
这看起来是确定要使用的参数大小的文件
InitializeParameter中的这部分初始化Size
int? determinedSize = DetermineParameterSize(sqlType, parameter);
if (determinedSize.HasValue) {
parameter.Size = determinedSize.Value;
}
然后执行路径对varchars设置为8000,对nvarchars设置为4000,并且实际上并没有查看该属性
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返回false,你可以在这里看到
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;
}
}
}
我在执行函数时逐步执行代码以查看其执行路径...在执行之前似乎没有任何有用的钩子可以修改.. SqlProvider没有任何用处来覆盖或挂钩进入......