Skip to content

NullReferenceException happens when collection is not retrieved before making query to database. #1

@MikhailCrimea

Description

@MikhailCrimea

First, thank you for good library!
I'm using it with .net 4.7.
I have two test methods with one small difference and different results.
TestNoException passes when TestException falling with NullReferenceException.

If this is behaviour by design, then it would be better to update docs (we must explicitly take collection before using it in Contains).
If not, it would be great to fix NullReferenceException.

I attach whole test project with initial migration and one table to reproduce issue.

    [TestFixture]
    public class TestCacheContains
    {
        [Test]
        public void TestNoException()
        {
            using (var db = new DataBaseContext())
            {
                db.TestEntities.CacheContains().Where(WhereConditionNoException()).ToList();
            }
        }

        [Test]
        public void TestException()
        {
            using (var db = new DataBaseContext())
            {
                db.TestEntities.CacheContains().Where(WhereConditionException()).ToList();
            }
        }

        private Expression<Func<TestEntity, bool>> WhereConditionException()
        {
            return c => SomeCollection.CollectionIds.Contains(c.Id);
        }

        private Expression<Func<TestEntity, bool>> WhereConditionNoException()
        {
            List<long> list = SomeCollection.CollectionIds;
            return c => list.Contains(c.Id);
        }
    }


    class SomeCollection
    {
        public static List<long> CollectionIds = new List<long> { 1, 2, 3 };
    }

Exception looks like this

System.NullReferenceException : Object reference not set to an instance of an object.
   at berkeleychurchill.CacheContains.ContainsRewriteVisitor.EvaluateExpression(Expression e)
   at berkeleychurchill.CacheContains.ContainsRewriteVisitor.EvaluateExpression(Expression e)
   at berkeleychurchill.CacheContains.ContainsRewriteVisitor.Rewrite(Expression target, MethodInfo method, Expression argument)
   at berkeleychurchill.CacheContains.ContainsRewriteVisitor.VisitMethodCall(MethodCallExpression e)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
   at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitArguments(IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at berkeleychurchill.CacheContains.ContainsRewriteVisitor.VisitMethodCall(MethodCallExpression e)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at berkeleychurchill.CacheContains.QueryableExtensions.CacheContainsWrapper`1.CreateQuery[U](Expression e)
   at System.Linq.Queryable.Where[TSource](IQueryable`1 source, Expression`1 predicate)
   at ConsoleApp1.TestCacheContains.TestException() in C:\...\ConsoleApp1\ConsoleApp1\TestCacheContains.cs:line 27

ConsoleApp1.zip

In terms of tests inside your projects falling test will look like this:

        [Test]
        public void TestCollectionNotRetrievedBeforeContainsCall()
        {
            var queryable = storeList.AsQueryable().CacheContains().Where(l => SomeCollection.CollectionIds.Contains(l));
        }

        class SomeCollection
        {
            public static List<int> CollectionIds = new List<int> { 3, 5, 7 };
        }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions