When invoke the expression in EF-Core Include Where clauses, i become an InvalidOperationException
variable ‘___zip_0’ of type ‘System.Int32’ referenced from scope ”, but it is not defined
DBContext configuration with LinqKit
UseSqlServer("Server=TMATEBOOK2023\SQLEXPRESS;Initial Catalog=Person;Trusted_Connection=True;TrustServerCertificate=true;")
.WithExpressionExpanding();
SpecificationBase class
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 zipExp = new AddressByZipSpecification(12).ToExpression();
var result = await dbContext.Person.Include(p => p.AddressList.Where(a => zipExp.Invoke(a))).ToListAsync();
The dbContext.Address.Where(ZipExp).ToListAsync()
works very well, i am confused what is happends with the declaration of variable in the zipExp expression.
If i replace the expression with it works well, too.
Expression<Func<Address, bool>> addressFilter = a => a.StreetNr > 199;