Linq to sql LINQ2SQL:如何实现通用的最大字符串长度验证?

Linq to sql LINQ2SQL:如何实现通用的最大字符串长度验证?,linq-to-sql,validation,Linq To Sql,Validation,LINQ2SQL中的一个常见问题是,尽管.NET字符串允许为其变量指定任何长度,但您的数据库可能具有特定的最大长度约束(如VARCHAR(5))。这将导致SQL错误消息“字符串或二进制数据将被截断”。这是非常没有帮助的,因为它不会告诉您哪些字段是罪魁祸首 显然,验证输入的最大字符串长度将是正确的方法。我面临的主要问题是为项目中的每个LINQ对象创建必要的验证,如果字段的最大长度被更新,则更新验证 理想情况下,我需要找到一种方法来动态确定生成字段的最大长度,这样我就不会忘记以后更新验证 到目前为止

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对象对其进行了测试,效果很好!通过一些修改,这是一个非常简单的解决方案,满足了我的大多数验证需求。非常感谢。