SubSonic 3 および MySQL、CleanUp() メソッドの列名からアンダースコアを削除すると、linq-query でプロパティを使用するときに例外が発生する
-
21-09-2019 - |
質問
MySQL で SubSonic 3(.0.0.3) ActiveRecord を使用しているときに問題が発生しました。
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"));
「メンバー 'EntityName' はサポートされていません。」というメッセージを含む NotSupportedException が発生します。
取り除いたら
result = result.Replace("_", "");
すべてが正常に動作しますが、Entity_Id のようなプロパティが得られるだけですが、これは私が望むものではありません。
なぜこのようなことが起こるのか知っている人がいたら、ぜひ聞きたいです。修正可能であれば、さらに良いです!目立ったものではありませんが、少し迷惑です。
解決
何ヶ月もの間、これは私にとって問題であり、サポートされている DB で 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));
}
次に、を変更する必要があります 構造体.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 はそれらをクリーンな状態と照合するようになります。 プロパティ名.