Inspiriert durch den Wunsch, Enumerationen in EF-Abfragen verwenden zu können, überlege ich, einen ExpressionVisitor zu meinen Repositorys hinzuzufügen, der eingehende Kriterien / Spezifikationen akzeptiert und sie so umschreibt, dass sie die entsprechende persistente int-Eigenschaft verwenden.
Ich verwende konsequent das folgende Wert-Suffix-Muster in meinen (Code-First) -Entitäten:
public class User : IEntity
{
public long ID { get; set; }
internal int MemberStatusValue { get; set; }
public MemberStatus MemberStatus
{
get { return (MemberStatus) MemberStatusValue; }
set { MemberStatusValue = (int) value; }
}
}
Und ordnen Sie dies der Datenbank zu, indem Sie Folgendes verwenden:
internal class UserMapping : AbstractMappingProvider<User>
{
public override void DefineModel( DbModelBuilder modelBuilder )
{
// adds ToTable and other general mappings
base.DefineModel( modelBuilder );
Map.Property( e => e.MemberStatusValue ).HasColumnName( "MemberStatus" );
}
}
In meinen Repositories habe ich folgende Methode:
public IQueryable<T> Query( Expression<Func<T, bool>> filter, params string[] children )
{
if( children == null || children.Length == 0 )
{
return Objects.Where( filter );
}
DbQuery<T> query = children.Aggregate<string, DbQuery<T>>( Objects, ( current, child ) => current.Include( child ) );
return filter != null ? query.Where( filter ) : query;
}
Ich möchte einen Methodenaufruf innerhalb dieser Methode hinzufügen, um den Filterausdruck neu zu schreiben und alle Verweise auf die MemberStatus-Eigenschaft durch Verweise auf MemberStatusValue zu ersetzen.
Ich nehme an, dass es eine Lösung sein wird, die etwas beinhaltet, was in diesem SO-Post zu sehen ist , aber ich bin mir nicht sicher, wie ich von der Idee zur Implementierung kommen soll.
Wenn Sie einen Hinweis auf die potenziellen Auswirkungen des Hinzufügens dieser Funktion auf die Leistung geben können, wäre dies ebenfalls hilfreich.
Ich bin mir nicht sicher, ob Sie genau danach streben, aber ich habe es einfacher gefunden, Enums auf ähnliche, aber etwas andere Weise zu behandeln. Ich habe zwei Eigenschaften, so wie Sie, aber meine Int-Eigenschaft ist public und ist, was die Datenbank persistent hält; Ich habe dann eine andere öffentliche "Wrapper" -Eigenschaft, die den int-Eigenschaftswert über Umwandlungen vom / zum gewünschten Aufzählungstyp erhält / setzt, was tatsächlich vom Rest der Anwendung verwendet wird.
Daher muss ich mich nicht mit dem Modell herumschlagen. EF versteht und beharrt die Int-Eigenschaft gerade gut, während der Rest der Anwendung nette Interaktionen mit dem Enum-Typ erhält. Das einzige, was ich an meinem Ansatz nicht mag, ist, dass ich meine LINQ-Anweisungen mit einer Reihe von Umwandlungen für jeden Aufzählungswert schreiben muss, den ich abfragen möchte, um ihn zu einem int zu machen, der mit dem tatsächlich bestehenden Feld übereinstimmt. Es ist jedoch ein kleiner Preis, und ich möchte es Ihnen vorschlagen, weil es scheint, dass Sie eine Zeichenfolge verwenden, um Ihre Abfrage zu generieren, die alle Typsicherheit, Intellisense usw., die LINQ bietet, aufgibt.
Wenn Sie sich für eine Anleitung interessieren, wie Sie die neuen enum-Funktionen in EF 5 verwenden können (die jetzt in der Beta-Version zum Download zur Verfügung stehen, wenn Sie es ausprobieren möchten), gehen Sie folgendermaßen vor: