2016-06-19 5 views
1

Ich versuche eine generische Methode zu erstellen, die ich überall in meiner Anwendung verwenden kann.Wie setze ich Lambda, wenn die Eigenschaften bis zur Laufzeit nicht bekannt sind?

Hier ist meine Methode:

public T GetEntry(ObjectId id) 
{ 
    IMongoCollection<T> collections = db.GetCollection<T>(database); 
    var getObj = collections.Find().FirstOrDefault();  // something like x => x.id == id 
    return getObj; 
} 

Find nimmt einen Lambda-Ausdruck, der die Einschränkungen angeben, aber ich kann es nicht gesetzt, da die Eigenschaften werden erst zur Laufzeit bekannt sein. Wie richte ich es ein?

Antwort

1

Sie können Schnittstelle verwenden für diese Lösung

public Interface IEntity 
{ 
    int Id {set ;get} 
} 


class EntryManagement<T> where T : IEntity 
{ 
    public T GetEntry(ObjectId id) 
    { 
     IMongoCollection<T> collections = db.GetCollection<T>(database); 
     var getObj = collections.Find(x => x.Id == id).FirstOrDefault();  
     return getObj; 
    } 
} 

oder Sie können Ihre Lambda-Ausdruck zur Laufzeit dynamisch

public T GetEntry(ObjectId id) 
{ 
    IMongoCollection<T> collections = db.GetCollection<T>(database); 
    var parameterExpression = Expression.Parameter(typeof(T), "object"); 
    var propertyOrFieldExpression = Expression.PropertyOrField(parameterExpression, "Id"); 
    var equalityExpression = Expression.Equal(propertyOrFieldExpression, Expression.Constant(id, typeof(int))); 
    var lambdaExpression = Expression.Lambda<Func<T, bool>>(equalityExpression, parameterExpression); 

    var getObj = collections.Find(lambdaExpression).FirstOrDefault(); 
    return getObj; 
} 
+0

Okay, habe ich versucht, Ihre zweite Lösung und es hat funktioniert !! Ich muss es nur in 'typeof (ObjectId)' ändern, da es 'ObjectId' und nicht' int' ist. Nur eine Frage. Wenn ich Ihre erste Lösung verwenden möchte, muss ich "IEntity" für alle meine Modellklassen implementieren? –

+0

@CarlosMiguelColanta Ja, ich vergesse zu erwähnen, dass für die erste Lösung alle Ihre Modellklassen IEntity implementieren müssen. Ich selbst bevorzuge die erste Lösung, weil es ein harter Typ ist. – Kahbazi

2

Haben Sie den Suchausdruck an den Anrufer ändern möchten erstellen? In diesem Fall ist es wahrscheinlich am einfachsten, den Ausdruck einfach vom Aufrufer zu übergeben. Etwas wie folgt aus:

public T GetEntry<T>(ObjectId id, Expression<Func<T, bool>> predicate) 
{ 
    IMongoCollection<T> collections = db.GetCollection<T>(database); 
    var getObj = collections.Find(predicate).FirstOrDefault(); // Call passed in predicate 
    return getObj; 
} 

Dann, wenn Sie die Funktion aufrufen Sie so etwas wie tun:

var person = GetEntry<Person>(id, person => person.Id == id); 
Verwandte Themen