Ormlite Where-Contains Fails
Asked Answered
T

2

5

I'm attempting to query my db using Enumerable.Contains inside a SqlExpressionVisitor.Whereclause. When the lambda is compiled, I'm getting a null reference exception.

When the visitor makes it to foreach (Object e in inArgs) (currently line 1067) inside SqlExpressionVisitor.VisitArrayMethodCall, it chokes because inArgs is null. The following is my sample that causes the error. I don't understand lambdas/expressions well enough to know why this is happening.

So my questions is, am I not using the Where clause properly or is this a bug?

class Program
{
    static void Main(string[] args)
    {
        var connectionFactory = new OrmLiteConnectionFactory(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database1.mdf;Integrated Security=True;User Instance=True", SqlServerDialect.Provider);
        SetupDb(connectionFactory);           

        using (var db = connectionFactory.OpenDbConnection())
        {
            var numbersToSelect = new int[2] { 1, 2 };
            db.Select<SomeObject>(e => e.Where(o => numbersToSelect.Contains(o.Number)));
        }
    }

    static void SetupDb(IDbConnectionFactory connectionFactory)
    {
        using (var db = connectionFactory.OpenDbConnection())
        {
            db.DropTable<SomeObject>();
            db.CreateTable<SomeObject>();
            db.Insert(new SomeObject { Number = 1 });
            db.Insert(new SomeObject { Number = 2 });
            db.Insert(new SomeObject { Number = 3 });
            db.Insert(new SomeObject { Number = 4 });
            db.Insert(new SomeObject { Number = 5 });
        }
    }
}

class SomeObject
{
    public int Number { get; set; }
}

After a little more digging, it turns out calling the compiled method is returning an int[] which causes the cast to object[] to be null. Casting to IEnumerable fixes my specific issue.

Changed

var getter = lambda.Compile();
var inArgs = getter() as object[];

to

var getter = lambda.Compile();
var inArgs = getter() as IEnumerable;

Not sure what sort of implications this has though (if any). Still looking for some guidance.

Tush answered 17/7, 2013 at 4:36 Comment(1)
It looks like there was an update to the ORMLite repository about 6 hours ago related to this specific issue.Gironde
T
2

Turns out it was a bug. It's been fixed for the sqlite visitor and the sql visitor as of commit 9f0b0e8 Thanks @mythz.

Tush answered 19/7, 2013 at 2:54 Comment(0)
W
8

Instead of using Contains, use Sql.In

db.Select<SomeObject>(e => e.Where(o => Sql.In(o.Number,numbersToSelect)));

Weed answered 18/7, 2013 at 0:42 Comment(1)
Sql.In doesn't work on non-sql stores (List<T>). The actual code I have is in a service layer which calls repositories that take an expression as a parameter.Tush
T
2

Turns out it was a bug. It's been fixed for the sqlite visitor and the sql visitor as of commit 9f0b0e8 Thanks @mythz.

Tush answered 19/7, 2013 at 2:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.