Linq to sql LINQ2SQL:如何实现通用的最大字符串长度验证?
LINQ2SQL中的一个常见问题是,尽管.NET字符串允许为其变量指定任何长度,但您的数据库可能具有特定的最大长度约束(如VARCHAR(5))。这将导致SQL错误消息“字符串或二进制数据将被截断”。这是非常没有帮助的,因为它不会告诉您哪些字段是罪魁祸首 显然,验证输入的最大字符串长度将是正确的方法。我面临的主要问题是为项目中的每个LINQ对象创建必要的验证,如果字段的最大长度被更新,则更新验证 理想情况下,我需要找到一种方法来动态确定生成字段的最大长度,这样我就不会忘记以后更新验证 到目前为止,我能找到的最好的实现是,它已经远远优于我所能想到的任何东西。唯一的不确定点是动态确定最大长度Linq to sql LINQ2SQL:如何实现通用的最大字符串长度验证?,linq-to-sql,validation,Linq To Sql,Validation,LINQ2SQL中的一个常见问题是,尽管.NET字符串允许为其变量指定任何长度,但您的数据库可能具有特定的最大长度约束(如VARCHAR(5))。这将导致SQL错误消息“字符串或二进制数据将被截断”。这是非常没有帮助的,因为它不会告诉您哪些字段是罪魁祸首 显然,验证输入的最大字符串长度将是正确的方法。我面临的主要问题是为项目中的每个LINQ对象创建必要的验证,如果字段的最大长度被更新,则更新验证 理想情况下,我需要找到一种方法来动态确定生成字段的最大长度,这样我就不会忘记以后更新验证 到目前为止
有没有人见过或实现过类似的东西 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!
}
公共类行
{
//通常由LINQ2SQL生成
[Column(Storage=“_Message”,DbType=“NVarChar(20)”)]
公共字符串消息
{
得到;
设置
}
//通常由LINQ2SQL生成
[Column(Storage=“_Property”,DbType=“NVarChar(20)NOT NULL”)]
公共字符串属性
{
得到;
设置
}
}
公共类VarCharInfo
{
公共int?MaxLen;
公共布尔值为空;
}
公共静态VarCharInfo GetVarCharInfo(PropertyInfo PropertyInfo)
{
var attrib=propertyInfo.GetCustomAttributes(typeof(ColumnAttribute),false)
第()类
.FirstOrDefault();
if(attrib==null | | attrib.DbType==null)
{
返回null;
}
var match=Regex.match(attrib.DbType,@“VarChar\((?'len'\d+))(?'notnull'notnull)?);
如果(!match.Success)
{
返回null;
}
var rvl=新的VarCharInfo();
rvl.MaxLen=int.Parse(match.Groups[“len”]。捕获[0]。值);
rvl.IsNullable=match.Groups[“notnull”]。成功;
返回rvl;
}
公共静态bool validateArchColumns(对象dataObject)
{
布尔成功=真;
foreach(dataObject.GetType()中的var propertyInfo)
.GetProperties()
.Where(pi=>pi.PropertyType==typeof(string)))
{
var vci=GetVarCharInfo(propertyInfo);
如果(vci!=null)
{
var currentValue=propertyInfo.getMethod()
.Invoke(dataObject,null)作为字符串;
if(currentValue==null)
{
如果(!vci.IsNullable)
{
//更多工作:值为空,但不应为空
成功=错误;
}
}
else if(vci.MaxLen!=null&¤tValue.Length>vci.MaxLen)
{
//更多工作:值比db允许的时间长
成功=错误;
}
}
}
回归成功;
}
静态void UsageTest()
{
行t=新行();
t、 Message=“此消息长度超过20个字符”;
//属性为空
validateArcColumns(t);//返回false!
}
我已经使用自己的LINQ对象对其进行了测试,效果很好!通过一些修改,这是一个非常简单的解决方案,满足了我的大多数验证需求。非常感谢。