Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
MikhailCrimea opened this issue Mar 6, 2021 · 0 comments

Comments

@MikhailCrimea
Copy link

MikhailCrimea commented Mar 6, 2021

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 };
        }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant