代码之家  ›  专栏  ›  技术社区  ›  rybosome

在C#中使用Linq to Sql,是否有任何方法可以自动截断过长的数据?

  •  2
  • rybosome  · 技术社区  · 15 年前

    所以,我将数据从一个数据库导入另一个数据库。大约有5000条记录(所以没什么可笑的,但也不小到足以吸引眼球)。有没有一种简单的方法可以自动截断过长的数据—特别是varchar字段?我不希望截断是静默的,因为太长的字段可能需要注意,但是如果一个长2个字符的名称不会在插入时失败,并且抛出一个完全不特定的异常,那就太好了。

    我想实现的解决方案是截短数据、插入数据并记录这些数据。还有人做过类似的事吗?

    3 回复  |  直到 15 年前
        1
  •  6
  •   Gabe Timothy Khouri    15 年前

    Linq2Sql将生成如下属性:

        [Column(Storage="_Name", DbType="NVarChar(50) NOT NULL")]
        public string Name
        {
            get
            {
                return this._Name;
            }
            set
            {
                if ((this._Name != value))
                {
                    this.OnNameChanging(value);
                    this.SendPropertyChanging();
                    this._Name = value;
                    this.SendPropertyChanged("Name");
                    this.OnNameChanged();
                }
            }
        }
    

    查看它如何调用 OnNameChanged ? 只需创建一个具有该名称的函数即可执行截断和日志记录:

    void OnNameChanged()
    {
        if (Name.Length > 50)
        {
            Name = Name.Substring(0, 50);
            LogSomehow("Name truncated");
        }
    }
    
        2
  •  0
  •   Robert Harvey    15 年前

    public static IEnumerable<string> Truncater(this IEnumerable<string> s, int len)
    {
        foreach( var str in s )
        {
            if( str.Length > len )
            {
                string outStr = str.Substring(0, len);
                Console.WriteLine(String.Format("Truncated {0} to {1}", str, outStr));
                yield return outStr;
            }
            else
                yield return str;
        }
    }
    
        3
  •  0
  •   shaunmartin    15 年前

    这里有一个更自动的方法。

    像这样使用:

                foreach (object insert in context.GetChangeSet().Inserts)
                {
                    FindLongStrings(update);
                }
    
                context.SubmitChanges();
    

    方法如下: (它的效率非常低,所以我不会把它放在生产代码中,但是如果您有一个一次性的转换/导入(听起来像是这样),它可能会起作用。)

        public static void FindLongStrings(object testObject)
        {
            foreach (PropertyInfo propInfo in testObject.GetType().GetProperties())
            {
                foreach (ColumnAttribute attribute in propInfo.GetCustomAttributes(typeof(ColumnAttribute), true))
                {
                    if (attribute.DbType.ToLower().Contains("varchar"))
                    {
                        // kinda crude, but it works...
                        string dbType = attribute.DbType.ToLower();
                        int numberStartIndex = dbType.IndexOf("varchar(") + 8;
                        int numberEndIndex = dbType.IndexOf(")", numberStartIndex);
                        string lengthString = dbType.Substring(numberStartIndex, (numberEndIndex - numberStartIndex));
                        int maxLength = 0;
                        int.TryParse(lengthString, out maxLength);
    
                        string currentValue = (string)propInfo.GetValue(testObject, null);
    
                        // Do your logging and truncation here
                        if (!string.IsNullOrEmpty(currentValue) && currentValue.Length > maxLength)
                            Console.WriteLine(testObject.GetType().Name + "." + propInfo.Name + " " + currentValue + " Max: " + maxLength);
    
                    }
                }
            }
        }