Используя Linq для Sql в C #, есть ли способ автоматически обрезать слишком длинные данные? - PullRequest
2 голосов
/ 10 сентября 2010

Итак, я импортирую данные из одной базы данных в другую.Есть около 5000 записей (так что ничего смешного, но недостаточно маленького, чтобы смотреть в глаза).Есть ли простой способ автоматически обрезать слишком длинные данные - в частности, поля varchar?Я не хочу, чтобы усечение было тихим, так как слишком длинные поля, вероятно, потребуют внимания, но было бы очень хорошо, если бы имя, длина которого составляла 2 символа, не сработало при вставке и выдало бы совершенно неспецифическое исключение.

Я бы хотел реализовать решение, которое урезает данные, вставляет их и записывает в журнал.Кто-нибудь еще делал что-то подобное?

Ответы [ 3 ]

6 голосов
/ 10 сентября 2010

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");
    }
}
0 голосов
/ 03 октября 2010

Вот более автоматический метод. Он просматривает тип / длину каждого вставляемого столбца на лету.

Используйте это так:

            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);

                }
            }
        }
    }
0 голосов
/ 10 сентября 2010

Я бы сделал метод итератора расширения, который вы могли бы добавить в свой запрос, выполнив что-то вроде этого:

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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...