Carlos Miguel Colanta
Carlos Miguel Colanta

Reputation: 2823

How to set the lambda if the properties won't be known until runtime?

I'm trying to make a generic method that I can use anywhere within my application.

Here is my method:

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 takes a lambda expression that will specify the constraints but I can't set it because the properties won't be known until runtime. How do I set it up?

Upvotes: 1

Views: 61

Answers (2)

Chris Tavares
Chris Tavares

Reputation: 30411

Do you want to change the search expression at the caller? In that case it's probably easiest to just pass in the expression from the caller. Something like this:

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;
}

Then when you call the function you can do something like:

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

Upvotes: 2

Kahbazi
Kahbazi

Reputation: 15005

You can use Interface for this solution

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;
     }
}

or you can create your lambda expression dynamically at runtime

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;
}

Upvotes: 1

Related Questions