LINQ2SQL中的一个常见问题是.NET String允许为其变量分配任何长度,而您的数据库可能具有特定的最大长度约束(如VARCHAR(5))。这将导致SQL错误消息“字符串或二进制数据将被截断。”,这是非常无益的,因为它不会告诉您哪些字段是罪魁祸首。
显然,验证输入的最大字符串长度将是正确的方法。我遇到的主要问题是为项目中的每个LINQ对象创建必要的验证,并在更新字段的最大长度时更新验证。
理想情况下,我需要找到一种方法来动态确定生成字段的最大长度,因此我不会忘记以后忘记更新验证。
到目前为止我能找到的最好的实现是"Integrating xVal Validation with Linq-to-Sql",这已经远远优于我能想到的任何东西。唯一不确定的点是动态确定最大长度。
有没有人见过或实施过类似的东西?
答案 0 :(得分:2)
LINQ2SQL代码生成器在属性字段上放置一个类似于:
的属性[Column(Storage="_Message", DbType="NVarChar(20)")]
在运行时提取和使用此信息会很简单:
public class Row
{
// normally generated by LINQ2SQL
[Column(Storage = "_Message", DbType = "NVarChar(20)")]
public string Message
{
get;
set;
}
// normally generated by LINQ2SQL
[Column(Storage = "_Property", DbType = "NVarChar(20) NOT NULL")]
public string Property
{
get;
set;
}
}
public class VarCharInfo
{
public int? MaxLen;
public bool IsNullable;
}
public static VarCharInfo GetVarCharInfo(PropertyInfo propertyInfo)
{
var attrib = propertyInfo.GetCustomAttributes(typeof(ColumnAttribute), false)
.OfType<ColumnAttribute>()
.FirstOrDefault();
if (attrib == null || attrib.DbType == null)
{
return null;
}
var match = Regex.Match(attrib.DbType, @"VarChar\((?'len'\d+)\)(?'notnull' NOT NULL)?");
if (!match.Success)
{
return null;
}
var rvl = new VarCharInfo();
rvl.MaxLen = int.Parse(match.Groups["len"].Captures[0].Value);
rvl.IsNullable = match.Groups["notnull"].Success;
return rvl;
}
public static bool ValidateVarCharColumns(object dataObject)
{
bool success = true;
foreach (var propertyInfo in dataObject.GetType()
.GetProperties()
.Where(pi => pi.PropertyType == typeof(string)))
{
var vci = GetVarCharInfo(propertyInfo);
if (vci != null)
{
var currentValue = propertyInfo.GetGetMethod()
.Invoke(dataObject, null) as string;
if (currentValue == null)
{
if (!vci.IsNullable)
{
// more work: value is null but it shouldn't be
success = false;
}
}
else if (vci.MaxLen != null && currentValue.Length > vci.MaxLen)
{
// more work: value is longer than db allows
success = false;
}
}
}
return success;
}
static void UsageTest()
{
Row t = new Row();
t.Message = "this message is longer than 20 characters";
// t.Property is null
ValidateVarCharColumns(t); // returns false!
}