在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服务器错误。
我可以强制 Linq To SQL 不忽略我传递的长度吗?
附言nvarchar(4000) 也有同样的问题。
浏览反编译的代码,在编写查询时看起来并没有真正关注该属性,而且我真的没有看到可以让您设置它的路径
这似乎是确定要使用的参数大小的文件
https://github.com/Microsoft/referencesource/blob/master/System.Data.Linq/SqlClient/SqlTypeSystemProvider.cs
初始化参数中的这部分初始化大小
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 没有任何有用的东西可以覆盖或挂钩到其中。