SubSonic 3 и MySQL, удаление подчеркивания из имени столбца в методе CleanUp () вызывает исключения при использовании свойства в linq-запросе - PullRequest
0 голосов
/ 18 февраля 2010

Я столкнулся с проблемой при использовании SubSonic 3 (.0.0.3) ActiveRecord с MySQL.

Поскольку MySQL не позволяет вам использовать заглавные буквы в именах таблиц или столбцов (или, скорее, игнорирует их, если вы это делаете), я решил разделить слова, используя подчеркивания, например. entity_id, а затем используйте метод CleanUp (), чтобы добавить регистр заголовков и удалить подчеркивания.
Друг написал метод ToTitleCase (string s), который выглядит так:

string ToTitleCase(string s)
{
    CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
    TextInfo textInfo = cultureInfo.TextInfo;
    return textInfo.ToTitleCase(s);
}

И метод CleanUp () выглядит так:

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

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

    //put your logic here...
    result = ToTitleCase(result);
    result = result.Replace("_", "");

    return result;
}

Если я тогда сделаю:

var entity = Entity.All().Where(e => e.EntityName.Contains("John"));

Я получаю NotSupportedException с сообщением «Элемент EntityName не поддерживается».

Если я удалю

result = result.Replace("_", "");

Все работает просто отлично, только я получаю свойства, похожие на Entity_Id, что не совсем то, что я хочу.

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

1 Ответ

2 голосов
/ 24 июня 2010

В течение многих месяцев это было проблемой для меня, и я просто избегал подчеркивания при работе с SubSonic на любой поддерживаемой БД.До вчерашнего дня, когда мне приходилось поддерживать устаревший проект, который имел подчеркивание в его базе данных SQL Server.

Вам придется исправить это в исходном коде SubSonic.Core (файл: SubSonic.Core \ Schema \ DatabaseTable.cs):

Найти этот метод:

public IColumn GetColumnByPropertyName(string PropertyName)
{
    return Columns.SingleOrDefault(x => x.Name.Equals(PropertyName, StringComparison.InvariantCultureIgnoreCase));
}

И измените его на:

public IColumn GetColumnByPropertyName(string PropertyName)
{
    return Columns.SingleOrDefault(x => x.PropertyName.Equals(PropertyName, StringComparison.InvariantCultureIgnoreCase));
}

Затем вам нужно будет изменить Structs.tt :

Найти это вверху:

Columns.Add(new DatabaseColumn("<#=col.Name#>", this)
{
    IsPrimaryKey = <#=col.IsPK.ToString().ToLower()#>,
    DataType = DbType.<#=col.DbType.ToString()#>,
    IsNullable = <#=col.IsNullable.ToString().ToLower()#>,
    AutoIncrement = <#=col.AutoIncrement.ToString().ToLower()#>,
    IsForeignKey = <#=col.IsForeignKey.ToString().ToLower()#>,
    MaxLength = <#=col.MaxLength#>
});

И добавьте эту строку:

    PropertyName = "<#=col.CleanName#>",

, чтобы получилось:

Columns.Add(new DatabaseColumn("<#=col.Name#>", this)
{
    PropertyName = "<#=col.CleanName#>",
    IsPrimaryKey = <#=col.IsPK.ToString().ToLower()#>,
    DataType = DbType.<#=col.DbType.ToString()#>,
    IsNullable = <#=col.IsNullable.ToString().ToLower()#>,
    AutoIncrement = <#=col.AutoIncrement.ToString().ToLower()#>,
    IsForeignKey = <#=col.IsForeignKey.ToString().ToLower()#>,
    MaxLength = <#=col.MaxLength#>
});

Проблема в том, что после очистки имен столбцов SubSonic пытается выполнитьнайдите действительные столбцы в своем запросе, сопоставив сгенерированные имена свойств SubSonic с исходными именами столбцов базы данных .

Эти изменения обеспечат соответствие SubSonic им сочищенное имя свойства .

...