0

I'm new and this is probably very trivial but I have the following method which works fine, using LINQ for MongoDB:

public T Single<T>(System.Linq.Expressions.Expression<Func<T, bool>> whereExpression) where T : class, new()
{
    T retval = default(T);
    using (var db = Mongo.Create(_connectionString))
    {
        retval = db.GetCollection<T>().AsQueryable()
                    .Where(whereExpression).SingleOrDefault();
    }
    return retval;
}

But I would like to add a "Select" to it (for projection) using a parameter as well, something that might look like this (which obviously doesn't work):

public T SingleWithSelect<T>(System.Linq.Expressions.Expression<Func<T, bool>> whereExpression, System.Linq.Expressions.Expression<Func<T, bool>> selectExpression) where T : class, new()
{
    T retval = default(T);
    using (var db = Mongo.Create(_connectionString))
    {
        retval = db.GetCollection<T>().AsQueryable()
                    .Where(whereExpression)
                    .Select(selectExpression)
                    .SingleOrDefault();
    }
    return retval;
}

In the hopes that it'll return something similar to the following:

var results = db.GetCollection<Entity>("Entities").AsQueryable()
.Where(i => i.Id == someId)
.Select(y => new { y.SomeEntity }).SingleOrDefault();

Essentially I just need to know how to pass the SELECT parameter into the return function - surprisingly hard to find the solution online when so unfamiliar with LINQ.

Thank you.

1 Answer 1

2

You need another generic type to represent the result of the Select call.

public TResult SingleWithSelect<T, TResult>(
    Expression<Func<T, bool>> whereExpression,
    Expression<Func<T, TResult>> selectExpression)
    where T : class, new()
{
    TResult retval = default(TResult);
    using (var db = Mongo.Create(_connectionString))
    {
        retval = db.GetCollection<T>().AsQueryable()
                    .Where(whereExpression)
                    .Select(selectExpression)
                    .SingleOrDefault();
    }
    return retval;
}
Sign up to request clarification or add additional context in comments.

7 Comments

That's great, thanks Tim! When calling the method using the following I'm getting an error message that I'm trying to implicitly convert Anonymous type to "SomeEntity", do you know how I could remedy that as well? Method call: var result = SingleWithSelect<Entity, SomeEntity>(x => x.Id == id, y => new { y.SomeEntity });
What do you want to return - an anonymous type like new { SomeEntity = y.SomeEntity }, or a SomeEntity? The <Entity, SomeEntity> says you want to return a SomeEntity. If you want to return an anonymous type, call var result = SingleWithSelect(x => x.Id ... etc.
I do want to return SomeEntity, I'm just having problems with the syntax (learning LINQ as I go with this)...
You probably want: var result = SingleWithSelect<Entity, SomeEntity>(x => x.Id == id, y => y.SomeEntity);. I'd still expect the <...> to be redundant - the compiler can normally figure this part out for itself.
One thing... db.GetCollection<T>().AsQueryable() -> load all collection from mongodb... I think it is not good.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.