Дозвуковой DAL не удается компиляции по столбцам, которые являются ключевыми словами - PullRequest
2 голосов
/ 03 сентября 2010

Я использую Subsonic 3 (Active Record), VS2010, Framework 3.5 против базы данных MySQL. Кто-то назвал столбец «строка». Я тебя не знаю.

Хорошо, я назвал некоторые объекты базы данных несколькими глупыми именами (как, например, именование таблицы SQL Server «Пользователь»), но ... давай! И я не могу изменить таблицу из-за зависимостей в приложении!

ОК. Я чувствую себя немного лучше, когда я немного выразил благодарность за то, что выслушал

Так что, конечно, в сгенерированном коде я получаю повсюду ошибки из строк вроде:

закрытая строка {}

Я не рассматриваю это как приоритетную ошибку для Subsonic, если только у других нет подобных проблем с другими именами столбцов. Есть ли какие-нибудь планы по этому поводу?

Спасибо

Пол

p.s. Я попытаюсь убедить других разработчиков изменить или разрешить мне изменить имя столбца, я знаю, что это реальное решение, но Subsonic может изящно обрабатывать недопустимые имена, возможно, что-то вроде способа .netTiers это (добавьте _safeName к имени, чтобы оно стало string_safeName).

Ответы [ 3 ]

1 голос
/ 05 сентября 2010

Возможно, я использовал не тот язык. Прежде чем я продолжил вносить изменения, я хотел убедиться, что это не все готово в каком-то списке приоритетов или где-то над ним работают. Вот способ, которым я пошел с этим.

В Settings.ttinclude:

string[] reservedWords = new string[]{"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", 
            "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", 
            "extern", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", 
            "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", 
            "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", 
            "struct", "switch", "this", "throw", "try", "typeof", "unit", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", 
            "void", "volatile", "while", "FALSE", "TRUE", "yield", "by", "descending", "from", "group", "into", "orderby", "select", 
            "var", "where" };

 string CleanUp(string tableName){
    string result=tableName;

    //strip blanks
    result=result.Replace(" ","");

    if(reservedWords.Contains(result)){
        result += "_SafeName";
    }
    //put your logic here...

    return result;
}

Функция CleanUp уже исправляет имена таблиц и столбцов, поэтому я разместил здесь свою логику. Я надеюсь, что я получил все зарезервированные слова ...

Это также относится к меньшему проекту, где база данных - MySQL.

Так что этот хак / патч предназначен только для c # / mysql, но его очень легко перенести на другие БД / языки.

0 голосов
/ 11 января 2011

Если вы измените метод LoadColumns, у вас все еще будут проблемы с внешними ключами, но вы можете заменить свой метод CleanUp (string tableName) в Setting.ttinclude на:

string CleanUp(string tableName){
        string result=tableName;

        //strip blanks
        result=result.Replace(" ","");

        //put your logic here...
        if (reservedWords.Contains(result)) {
            result = "_" + result;
        }

        return result;
    }

это сработало как очарование для меня.

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

Вы можете исправить это сами очень легко.

Откройте файл SQLServer.ttinclude. Это файл шаблона T4, который SubSonic использует для генерации вашего кода.

Почти на полпути вниз, в строке 155 вы найдете функцию LoadColumns:

List<Column> LoadColumns(Table tbl){
    var result=new List<Column>();
    var cmd=GetCommand(COLUMN_SQL);
    cmd.Parameters.AddWithValue("@tableName",tbl.Name);

    using(IDataReader rdr=cmd.ExecuteReader(CommandBehavior.CloseConnection)){
        while(rdr.Read()){
            Column col=new Column();
            col.Name=rdr["ColumnName"].ToString();
            col.CleanName=CleanUp(col.Name);
            col.DataType=rdr["DataType"].ToString();
            col.SysType=GetSysType(col.DataType);
            col.DbType=GetDbType(col.DataType);
            col.AutoIncrement=rdr["IsIdentity"].ToString()=="1";
            col.IsNullable=rdr["IsNullable"].ToString()=="YES";
            int.TryParse(rdr["MaxLength"].ToString(),out col.MaxLength);

            result.Add(col);
        }

    }

    return result;
}

Просто добавьте логику здесь, в этой функции, когда она присваивает имя, которое нужно изменить, от имени столбца в вашей базе данных, "string", к чему-то более разумному.

List<Column> LoadColumns(Table tbl){
    var result=new List<Column>();
    var cmd=GetCommand(COLUMN_SQL);
    cmd.Parameters.AddWithValue("@tableName",tbl.Name);

    using(IDataReader rdr=cmd.ExecuteReader(CommandBehavior.CloseConnection)){
        while(rdr.Read()){
            Column col=new Column();

            var rawName = rdr["ColumnName"].ToString();
            if (rawName.Equals("string")) {
                col.Name="StringColumn";
            } else {
                col.Name=rawName;
            }

            col.CleanName=CleanUp(col.Name);
            col.DataType=rdr["DataType"].ToString();
            col.SysType=GetSysType(col.DataType);
            col.DbType=GetDbType(col.DataType);
            col.AutoIncrement=rdr["IsIdentity"].ToString()=="1";
            col.IsNullable=rdr["IsNullable"].ToString()=="YES";
            int.TryParse(rdr["MaxLength"].ToString(),out col.MaxLength);

            result.Add(col);
        }

    }

    return result;
}

Кроме того, если бы вы потратили некоторое время на него и заставили его обрабатывать все ключевые слова (скажем, путем поиска в статическом словаре и изменять имена, добавляя общий суффикс или подстановку словаря), тогда вы могли бы отправить патч обратно проект и вклад вместо того, чтобы пытаться уговорить других разработчиков сделать это.

...