我正在使用ActiveRecord SubSonic3模板。一切都工作得很花哨,然后我觉得我希望事情看起来好一点。请参阅我的数据库具有如下所示的字段:
SomeKey_id
SomeOtherKey_id
我想清理一下,以便它可以
SomeKeyID
SomeOtherKeyID
通过SubSonic访问时。
所以我将这个小东西添加到settings.ttinclude
if(Regex.IsMatch(result,".*_id",RegexOptions.IgnoreCase)){
result=result.Substring(0,result.Length-3);
result+="ID";
}
现在虽然我已加入ID
字段,但它已无法运行。
例如:
var data=from f in Foo
join b in Bar on f.FooID equals b.FooID
select new{FooValue=f, BarValue=b};
不起作用。
它会产生这个例外:
不支持会员'FooID'
然而,在我做_id
修复之前,它完美无缺。怎么了?我该如何解决这个问题?
Stacktrace是at pastebin
答案 0 :(得分:0)
CleanUp功能运行的是什么?它是否在代码模板的输出上运行,即SubSonic生成的自动生成的C#代码?当然,您需要使用此自动生成的代码来引用您正在访问的正确数据库列。如果您的数据库列实际上被称为SomeKey_id
并且您在代码中将其更改为SomeKeyID
,那么当然SubSonic将无法找到该数据库列。换句话说,您如何确保仅替换将在C#代码中使用的标识符,但不引用数据库列的标识符?
答案 1 :(得分:0)
问题出现在SubSonic.Core,我怀疑。我下载了它的源代码并在Schema / DatabaseTable.cs中我必须将GetColumnByPropertyName
函数更改为:
public IColumn GetColumnByPropertyName(string PropertyName)
{
var c = Columns.SingleOrDefault(x => x.Name.Equals(PropertyName, StringComparison.InvariantCultureIgnoreCase));
if (c == null)
{
c=Columns.SingleOrDefault(x => CleanUpColumnName(x.Name).Equals(PropertyName, StringComparison.InvariantCultureIgnoreCase));
if (c == null)
{
throw new NotSupportedException("Couldn't find column name");
}
}
return c;
}
private string CleanUpColumnName(string name)
{
//don't forget to change Settings.ttinclude:CleanUp when changing this function!
string result = name;
if (result.EndsWith("_id", StringComparison.OrdinalIgnoreCase))
{
result = result.Substring(0, result.Length - 3);
result += "RID";
}
return result;
}
这样做的原因是,当它尝试将列名解析为适当表中的IColumn时,所有它都具有类似“FooID”的内容,并且所有列都具有.Name
“Foo_id”。因此,我这样做,如果它第一次没有找到列,那么它将在每个列名称上第二次运行CleanUp函数,以便它可以找到匹配项。
如果SubSonic的某人读到这篇文章,我会很高兴,如果你以某种方式修补了这个bug或者至少注意到了它。请注意我正在使用的版本(以及我正在使用的源代码)是3.0.0.4
修改强>
实际上它比这更复杂。我最终必须在SubSonic中向IColumn和DataColumn添加一个CleanName字段,然后在运行T4模板时填写CleanName。然后我将上面的行改为
var c = Columns.SingleOrDefault(x => x.CleanName.Equals(PropertyName, StringComparison.InvariantCultureIgnoreCase));
然后在很多随机的地方我不得不改变这样的代码:
ParameterValue = settings[tbl.PrimaryKey.Name],
代码如下:
ParameterValue = settings[tbl.PrimaryKey.CleanName],
我仍然不确定我是否完成了所有更改,但我可以更新,插入,选择和加入,所以我会说如果没有,我会很接近。