SubSonic 3 e MySQL, rimozione di sottolineatura nome della colonna in cleanup () metodo fa sì che le eccezioni quando si utilizzano proprietà in LINQ-query
-
21-09-2019 - |
Domanda
ho incontrato un problema quando si utilizza SubSonic 3 (.0.0.3) ActiveRecord con MySQL.
Dato che MySQL non consente di utilizzare le lettere maiuscole nei nomi di tabella o colonna (o meglio, non tiene conto, se si fa) ho deciso di separare le parole mediante sottolineatura, per esempio ENTITY_ID, e quindi utilizzare il metodo di pulitura () per aggiungere involucro titolo e rimuovere le sottolineature.
Un amico ha scritto un metodo ToTitleCase (string s) che assomiglia a questo:
string ToTitleCase(string s)
{
CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
TextInfo textInfo = cultureInfo.TextInfo;
return textInfo.ToTitleCase(s);
}
E il metodo di pulitura () è simile al seguente:
string CleanUp(string tableName){
string result=tableName;
//strip blanks
result=result.Replace(" ","");
//put your logic here...
result = ToTitleCase(result);
result = result.Replace("_", "");
return result;
}
Se dunque io faccio:
var entity = Entity.All().Where(e => e.EntityName.Contains("John"));
ho un NotSupportedException, con il messaggio "Il membro del 'EntityName' non è supportato."
Se rimuovo
result = result.Replace("_", "");
Tutto funziona bene, solo io ottenere le proprietà cercando come ENTITY_ID che non è proprio quello che voglio.
Se qualcuno sa perché questo accada, mi piacerebbe sentire. Se è possibile fissare, ancora meglio! Non è un bloccante, ma è un po 'fastidioso.
Soluzione
Per molti molti mesi questo è stato un problema per me e ho appena evitato di sottolineatura quando si lavora con SubSonic su qualsiasi DB supportato. Fino a ieri quando ho dovuto sostenere un progetto che ha avuto un'eredità di sottolineatura nel suo database SQL Server.
Si dovrà risolvere il problema all'interno del codice sorgente del SubSonic.Core (file: SubSonic.Core \ Schema \ DatabaseTable.cs):
Trova questo metodo:
public IColumn GetColumnByPropertyName(string PropertyName)
{
return Columns.SingleOrDefault(x => x.Name.Equals(PropertyName, StringComparison.InvariantCultureIgnoreCase));
}
E modificarla in:
public IColumn GetColumnByPropertyName(string PropertyName)
{
return Columns.SingleOrDefault(x => x.PropertyName.Equals(PropertyName, StringComparison.InvariantCultureIgnoreCase));
}
Avanti dovrete modificare il vostro Structs.tt :
Trova questo vicino alla cima:
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#>
});
E aggiungere questa riga:
PropertyName = "<#=col.CleanName#>",
In modo che diventa:
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#>
});
Il problema è che una volta ripulito i nomi delle colonne, SubSonic prova il ritrovamento delle colonne valide nella query raddoppiando il tuo SubSonic generato nomi proprietà contro nomi originali delle colonne del database .
Queste modifiche faranno in modo che sia SubSonic abbinandoli contro il pulito nome della proprietà .