2009-03-25 13 views
2

Wie vermeiden Sie die Verwendung von fest codierten Tabellen- und Feldnamen im Entity-Framework? Zum Beispiel:Wie vermeidet man hartcodierte Feldnamen im Entity Framework?

Contact contact = 
     contactQuery.Include("SalesOrderHeader.SalesOrderDetail") 
     .FirstOrDefault(); 

Gibt es eine Möglichkeit, diese Informationen aus dem Kontext oder Metadaten zu erhalten? Ich würde gerne in der Lage sein, SalesOrderHeader.TableName oder SalesOrderHeaderFields.SalesOrderDetails.FieldName

Antwort

2

gesegnet Wenn Sie das Entity Frameworks Metadaten verwenden möchten, müssen Sie durch die MetadataWorkspace gehen suchen, die die ObjectContext hängt ab.

Der Ausgangspunkt ist, den EntityType für Ihren Basistyp zu erhalten, in Ihrem Fall Kontakt.

Ich habe ein EF tips series und in Tip 13 ich eine Erweiterungsmethode auf MetadataWorkspace zeigen, dass die EntityType für eine bestimmte CLR-Typ bekommt:

public static EntityType GetCSpaceEntityType<T>(
     this MetadataWorkspace workspace); 

Sie können dies wie folgt verwenden:

var contactEntity = ctx.MetadataWorkspace.GetCSpaceEntityType<Contact>(); 

Einmal Sie haben dies können Sie sehen, es ist NavigationProperties, um die Beziehung und die Namen, die Sie interessiert sind einschließlich:

heißt

foreach(var np in contactEntity.NavigationProperties) 
{ 
    Console.WriteLine("Include: {0}", np.Name); 
    Console.WriteLine("... Recursively include "); 
    EntityType relatedType = 
     (np.ToEndMember.TypeUsage.EdmType as RefType).ElementType; 
    //TODO: go repeat the same process... i.e. look at the relatedTypes 
    // navProps too until you decide to stop. 
} 

Natürlich, wie Sie entscheiden, was Sie wollen, Sie können bis zu Ihnen ist. this helps

Alex

1

Es ist nur ein Name der Eigenschaft, so dass Sie es über Reflexion erhalten können.

+2

Ich denke, aber Reflektion ist sehr teuer. – Vitalik

+0

Nicht wirklich. Es ändert sich nie, also müssen Sie es nur einmal tun. Machen Sie es zu einer Klasse statische Eigenschaft. Es wird in Mikrosekunden initialisiert und Sie müssen es nie wieder tun. –

+0

Ich habe eine bessere sehr dynamische Lösung mit Ausdruck Bäumen, siehe meine Antwort: http: // Stackoverflow.com/questions/683960/how-to-avoid-hardcoded-Feldnamen-in-entity-framework/3433134 # 3433134 – Shimmy

0

Beispiel (würde gerne bessere Ideen hören, fanden keinen Weg, einen Typnamen als Referenz wie die VB GetType tut zu akzeptieren):

VB:

<Extension()> 
Function GetRelation(Of TEntity As Type)(entity As TEntity, 
ParamArray path() As TEntity) As String 
    GetRelation = entity.Name 
    For Each type In path 
    GetRelation &= "." & type.Name 
    Next 
End Function 

'Here is your line: 
Dim x = Context.Employee.Include(
GetType(Contact).GetRelation(GetType(SalesOrderHeader), 
GetType(SalesOrderDetail))) 

C#:

static string GetRelation<TEntity>(this TEntity entity, params TEntity[] path) 
where TEntity : Type 
{ 
    string ret = entity.Name; 
    foreach (TEntity type in path) ret += "." + type.Name; 
    return ret; 
} 

//Put your line here: 
var x = context.Employee.Include(typeof(Contact).GetRelation(
typeof(SalesOrderHeader), 
typeof salesOrderDetail))); 

ich es wünsche eine dynamische Art und Weise der Reflexion wäre ... Noch einmal, ich bin offen, würden irgendwelche Vorschläge Dank

+0

Versuchen, wo TENtity zu ersetzen: Geben Sie mit etwas dynamischer ... – Shimmy

+0

Dieser Code wird nicht funktionieren. Sie müssen Entitätsgruppen- und -eigenschaftsnamen und keine Namen angeben. Der angegebene Code generiert ein falsches Argument beim Aufruf von Include –

+0

..., es sei denn, die Eigenschaftsnamen und Entitätsgruppennamen sind zufällig identisch mit dem Typnamen. –

Verwandte Themen