使用 CleanUp 后 SubSonic 3 Linq 加入错误
我正在使用 ActiveRecord SubSonic3 模板。一切都很顺利,然后我决定想让事情看起来更好一点。看到我的数据库有如下所示的字段:
SomeKey_id
SomeOtherKey_id
我想清理它,以便
SomeKeyID
SomeOtherKeyID
通过 SubSonic 访问它时会出现这样的情况。
因此,我将这个小东西添加到了 settings.ttinclude
的 CleanUp 函数中。
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 位于 pastebin
I am using the ActiveRecord SubSonic3 templates. Everything was working just dandy, then I decided I wanted things to look a bit better. See my database has field that look like this:
SomeKey_id
SomeOtherKey_id
I wanted to clean it up so that it would instead be
SomeKeyID
SomeOtherKeyID
when accessing it through SubSonic.
So I added this small thing to the CleanUp function of settings.ttinclude
if(Regex.IsMatch(result,".*_id",RegexOptions.IgnoreCase)){
result=result.Substring(0,result.Length-3);
result+="ID";
}
Now though everywhere I have joins on an ID
field it no longer works.
For example:
var data=from f in Foo
join b in Bar on f.FooID equals b.FooID
select new{FooValue=f, BarValue=b};
Does not work.
It will yield this exception:
The member 'FooID' is not supported
However before I did the _id
fix it worked perfectly. What is wrong? How do I work around this?
Stacktrace is at pastebin
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
CleanUp 功能在什么上运行?它是否在代码模板的输出(即 SubSonic 生成的自动生成的 C# 代码)上运行?当然,您需要此自动生成的代码来引用您正在访问的正确数据库列。如果您的数据库列实际上名为
SomeKey_id
并且您在代码中将其更改为SomeKeyID
,那么 SubSonic 当然将无法找到该数据库列。换句话说,如何确保仅替换将在 C# 代码中使用的标识符,而不是引用数据库列的标识符?What does the CleanUp function run on? Does it run on the output of the code templates, i.e. the auto-generated C# code that SubSonic generates? Surely you need this auto-generated code to refer to the correct database columns that you are accessing. If your database column is actually called
SomeKey_id
and you change that toSomeKeyID
in the code, then of course SubSonic will be unable to locate that database column. In other words, how are you making sure that you are replacing only the identifiers that you will be using in C# code, but not the identifiers that refer to the database columns?正如我怀疑的那样,问题出在 SubSonic.Core 中。我下载了它的源代码,在 Schema/DatabaseTable.cs 中,我必须将
GetColumnByPropertyName
函数更改为如下所示:这样做的原因是,当它尝试将列名称解析为 IColumn 时,相应的表具有类似于“FooID”的内容,并且所有列的
.Name
均为“Foo_id”。因此,我这样做是为了如果第一次没有找到该列,那么它将对每个列名称第二次运行 CleanUp 函数,以便找到匹配项。如果 SubSonic 的有人读到了这篇文章,我希望你能以某种方式修补这个错误或者至少注意到它。请注意我正在使用的版本(以及我正在使用的源)是 3.0.0.4
编辑:
实际上它比这更复杂。我最终必须向 SubSonic 中的 IColumn 和 DataColumn 添加 CleanName 字段,然后在 T4 模板运行时填写 CleanName。然后我将上面的行更改为类似的内容
然后在很多随机的地方我必须更改这样的代码:
更改为这样的代码:
我仍然不确定我是否已完成所有更改,但我可以更新,插入,选择并加入,如果没有,我会说我已经很接近了。
The problem was in SubSonic.Core as I suspected. I downloaded the source for it and in Schema/DatabaseTable.cs I had to change the
GetColumnByPropertyName
function to something like this:The reason for this is that when it tries to resolve the column name to an IColumn in the appropriate table all it has is something like "FooID" and all the columns have a
.Name
of "Foo_id". So, I made it so that if it doesn't find the column the first time then it will run the CleanUp function the second time on each of the column names so that it can find a match.If someone from SubSonic reads this, I'd love if you somehow patched this bug or at least gave notice of it. Note the version I'm using(and the source I'm using) is 3.0.0.4
EDIT:
Actually it's more complicated than this. I ended up having to add a CleanName field to IColumn and DataColumn in SubSonic and then fill in the CleanName from when the T4 templates run. Then I changed the line above to something like
Then in lots of random places I had to change code like this:
to code like this:
I'm still not sure that I've gotten all the changes complete but I can update, insert, select, and join so I'd say I'm close if not.