SubSonic 3和MySQL,从CleanUp()方法中的列名中删除下划线会导致在linq-query中使用属性时出现异常

时间:2010-02-18 07:16:52

标签: mysql subsonic subsonic3 subsonic-active-record

在使用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 个答案:

答案 0 :(得分:2)

很多个月对我来说这是一个问题,我在任何支持的数据库上使用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将其与已清理的属性名称进行匹配。