代码之家  ›  专栏  ›  技术社区  ›  Earlz

使用清理后的亚音速3直线连接错误

  •  1
  • Earlz  · 技术社区  · 14 年前

    我使用的是ActiveRecord Subsonic3模板。一切都很顺利,然后我决定让一切看起来好一点。请参见我的数据库中有如下字段:

    SomeKey_id
    SomeOtherKey_id
    

    我想把它清理干净

    SomeKeyID
    SomeOtherKeyID
    

    当通过亚音速进入时。

    所以我把这个小东西添加到了 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

    2 回复  |  直到 14 年前
        1
  •  0
  •   Timwi    14 年前

    清除功能运行在什么上?它是否运行在代码模板的输出上,即子音速生成的自动生成的C代码上?当然,您需要这个自动生成的代码来引用您正在访问的正确的数据库列。如果实际调用了数据库列 SomeKey_id 你把它改成 SomeKeyID 当然,在代码中,Subsonic将无法定位该数据库列。换句话说,您如何确保只替换将在C代码中使用的标识符,但是 引用数据库列的标识符?

        2
  •  0
  •   James McNellis    14 年前

    我怀疑问题是在亚音速的核心。我下载了它的源代码,在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 “FuffiID”。所以,我这样做的目的是,如果它第一次没有找到列,那么它将对每个列名第二次运行cleanup函数,以便找到匹配的列。

    如果亚音速的人读到了这个,我希望你能修补或者至少注意到这个缺陷。注意,我使用的版本(以及我使用的源代码)是3.0.0.4

    编辑:

    实际上,这比这更复杂。我最后不得不在子音速中向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],
    

    我仍然不确定我已经完成了所有的更改,但是我可以更新、插入、选择和加入,所以如果没有,我会说我已经完成了。

    推荐文章