在使用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这样的属性并不是我想要的。
如果有人知道为什么会这样,我很乐意听到。如果可以修复,甚至更好!它没有任何显示,但它有点烦人。
答案 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将其与已清理的属性名称进行匹配。