LINQ2SQL:如何实现通用的最大字符串长度验证? [英] LINQ2SQL: How to implement a generic maximum string length validation?

查看:153
本文介绍了LINQ2SQL:如何实现通用的最大字符串长度验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

LINQ2SQL中的一个常见问题是.NET字符串允许为其变量分配任何长度,而您的数据库可能具有特定的最大长度约束(例如VARCHAR(5)).这将导致SQL错误消息字符串或二进制数据将被截断.",由于它不会告诉您哪些字段是罪魁祸首,因此非常无济于事.

A common problem in LINQ2SQL is while the .NET String allows assigning any length to its variable, your database may have a specific max length constraint (like VARCHAR(5)). This will lead to the SQL error message "String or binary data would be truncated.", which is extremely unhelpful since it doesn't tell you which fields is the culprit.

显然,验证输入的最大字符串长度将是正确的方法.我面临的主要问题是为项目中的每个LINQ对象创建必要的验证,并在更新字段的最大长度时更新验证.

Obviously, validating the input for the maximum string length will be the correct way. The main problem I faced is creating the necessary validation for every LINQ object in my project, and updating the validation if the maximum length of the field is updated.

理想情况下,我需要找到一种方法来动态确定所生成字段的最大长度,因此不必冒险以后再更新验证.

Ideally, I need to work out a way to dynamically determine the max length of a generated field, so I do not risk forgetting to update the validation later.

到目前为止,我能找到的最好的实现是,它已经远远超过我能想到的任何东西.唯一不确定的点是动态确定最大长度.

The best possible implementation I can find so far is "Integrating xVal Validation with Linq-to-Sql", which is already far superior to anything I can think. The only uncertain point is the dynamically determine the max length.

有人见过或实施过类似的东西吗?

Has anyone seen or implemented anything similar?

推荐答案

LINQ2SQL代码生成器在类似于以下内容的属性字段上放置一个属性:

The LINQ2SQL code generator places an attribute on property fields similar to:

[Column(Storage="_Message", DbType="NVarChar(20)")]

在运行时提取和使用此信息很简单:

It would be simple to extract and use this information at runtime:

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:如何实现通用的最大字符串长度验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆