Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ormlite Where-Contains Fails

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.

like image 992
Chris Avatar asked Jul 17 '13 04:07

Chris


2 Answers

Instead of using Contains, use Sql.In

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

like image 169
Guru Kathiresan Avatar answered Sep 22 '22 14:09

Guru Kathiresan


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

like image 33
Chris Avatar answered Sep 21 '22 14:09

Chris