Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

EF Core 8 specification pattern variable referenced from scope ', but it is not defined

When invoke the expression, i become an InvalidOperationException

variable ‘___zip_0’ of type ‘System.Int32’ referenced from scope ”, but it is not defined

SpecificationBase class

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

     public abstract class Specification<TEntity> where TEntity : class
        {
            public abstract Expression<Func<TEntity, bool>> ToExpression();
        
            public bool IsSatisfiedBy(TEntity entity)
            {
                Func<TEntity, bool> predicate = ToExpression().Compile();
                return predicate(entity);
            }
           
            public Specification()
            {
                
            }
            public Specification( Expression<Func<TEntity,bool>>? criteria) 
                => Criteria = criteria;
            public Expression<Func<TEntity, bool>> Criteria { get; set; }
        
            public List<Expression<Func<TEntity, object>>> IncludeExpression { get; } = new();
            public List<Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>>> NestedIncludes { get; }
                    = new List<Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>>>();
            public List<string> IncludeStrings { get; } = new List<string>();
            public Expression<Func<TEntity,object>>? OrderByExpression { get; private set; }
            public Expression<Func<TEntity,object>>? OrderByDescendingExpression { get; private set; }
        
            protected void AddInclude(Expression<Func<TEntity,object>> includeExpression)=> IncludeExpression.Add(includeExpression);
            protected virtual void AddNestedInclude(Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> nestedIncludeExpression)
            {
                NestedIncludes.Add(nestedIncludeExpression);
            }
            protected virtual void AddInclude(string includeString)
            {
                IncludeStrings.Add(includeString);
            }
            protected void AddOrderBy(Expression<Func<TEntity, object>> orderByExpression)
                => OrderByExpression = orderByExpression;
        
            protected void AddOrderByDescending(Expression<Func<TEntity, object>> orderByDescendingExpression)
               => OrderByDescendingExpression = orderByDescendingExpression;
        
            public Specification<TEntity> And(Specification<TEntity> specification)
            {
                return new AndSpecification<TEntity>(this, specification);
            }
           
            public Specification<TEntity> Or(Specification<TEntity> specification)
            {
                return new OrSpecification<TEntity>(this, specification);
            }
           
        }
    

Specification in use

          
   public class AddressByZipSpecification : Specification<Address>
        {
                public int _zip { get; set; }
                public AddressByZipSpecification(int zip)
                {
                    _zip = zip;
                }
                public override Expression<Func<Address, bool>> ToExpression()
                {
                    return address => address.Zip == _zip;
                }
        }

How i use the specification in the test

 var zipSpec = new AddressByZipSpecification(12);
  var address = await dbContext.Address.Where(a =>  zipSpec.ToExpression().Invoke(a)).ToListAsync();

I am at a loss, what happend in the expression tree

>Solution :

You can’t Invoke an Expression inside another EF Core Expression and expect it to work.

Your easiest option is to cache the Expression and pass it in directly

var zipExpr = zipSpec.ToExpression();
var address = await dbContext.Address.Where(zipExpr).ToListAsync();

If you need to combine this expression with other expressionn then you may want to look at LinqKit, which can transform expression calls within other expressions.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading