Jon Archway
Jon Archway

Reputation: 4892

Expression and Parameter

I have this method:

public static Expression<Func<MyEntity, bool>> MyMethod(string someId)
    {
        return o => o.SomeProperty.Equals(someId);
    }

This is being passed to another method that uses entity framework with this expression to retrieve the matching items. My problem is it doesn't work. If I replace the someId as part of the Equals call with an actual value it works. However, it doesn't work if I pass the same value into this method above.

Does this mean the someId parameter doesn't get evaluated until the expression is actually used and therefore doesn't contain the actual value? Sorry, getting a bit confused here.

Thanks

Update:

Some debug info for the one that DOES work where the param is hard coded

.Lambda #Lambda1<System.Func`2[MyEntity,System.Boolean]>(MyEntity $t) {\r\n    .Call ($t.SomeProperty).Equals(\"test1\")

Some debug info for the one that DOES NOT work where the value is passed into the method

.Lambda #Lambda1<System.Func`2[MyEntity,System.Boolean]>(MyEntity $t) {\r\n    .Call ($t.SomeProperty).Equals(.Constant<MyEntity+<>c__DisplayClass4>(MyEntity+<>c__DisplayClass4).someId)

I am guessing when the value is not hard coded the expression has got a reference to something that doesn't exist? Sorry, getting myself in a muddle with what is going on here!

Update 2:

This is where it is being used - a method in a repository class:

public MyEntity Get(string someId)
{
   var queryPredicate = MyEntity.MyMethod(someId);
   var foundEntity = this.Query(queryPredicate);
}

Query is a method on the repository base class as below:

public IEnumerable<TEntity> Query(Expression<Func<TEntity, bool>> predicate)
{
    if (predicate == null)
    {
        throw new ArgumentNullException("predicate");
    }
    using (var context = new TContext())
    {
        return context.CreateObjectSet<TEntity>().AsExpandable().Where(predicate).ToList();
    }
}

Upvotes: 0

Views: 170

Answers (3)

wasatz
wasatz

Reputation: 4288

This sounds like a problem where LinqKit can be the solution you are looking for:

http://www.albahari.com/nutshell/linqkit.aspx

Have a look at it and see if it solves it :)

Upvotes: 1

James Curran
James Curran

Reputation: 103575

I don't have a compile hnady to test this, but from the IL code, it seems to be create a closure for someId. Basically, it's creating a func/expression which will be compiled & executed later, and the compile assumes that you'll want the value of someId at the time it's run, rather than at the time the expression was created. I think if you pass it through a temp, it should work.

public static Expression<Func<MyEntity, bool>> MyMethod(string someId) 
{ 
    string tempSomeId = someId;
    return o => o.SomeProperty.Equals(tempSomeId); 
} 

Upvotes: 0

Sylvain Perron
Sylvain Perron

Reputation: 413

Are you sure that the given value is not null? Can you give the exception it throws? Maybe it's a "int" that you need to pass as a ID?

Upvotes: 0

Related Questions