locked
sqlite can't comile lambda any() RRS feed

  • Question

  • I'm trying to run a query to get all of the items where an ID is equal to any integers in an array[int]. I tried:

    db.Table<JpFlashCard.Classes.Kana>().Where(a => ints.Any(i => i == a.RowID));

    but I get a can't compile lambda expression error. How can I do this without using linq? I'm assuming that running everything in this syntax is better than something like
    var kanas = from a in db.Table<Kanas> where ints.Any(i => a.RowID = I) select a;

    since, from what I understand, SQLite would get the whole table and then linq would select from that.

    Michael DiLeo

    Tuesday, September 3, 2013 7:14 PM

Answers

  • Those two queries are identical.  LINQ is just syntactic sugar for the pipeline of extension methods in the non-LINQ version.  The important thing is those are queries, and they are being interpreted by a provider and transformed into a source query.

    If the provider can't transform your query, you can send it simpler query, and then filter the results using LINQ 2 Objects

    Since your data is already in memory you can just write:

    db.Table<JpFlashCard.Classes.Kana>().AsEnumerable().Where(a => ints.Any(i => i == a.RowID));


    Methods like AsEnumerable(), ToList(), First(), FirstOrDefault() will actually execute the query and return a collection of objects, which can be further filtered and transformed.

    Also you can play with equivalent queries to see if you find one that will translate,

    db.Table<JpFlashCard.Classes.Kana>().Where(a => ints.Contains(a.RowId)) )

    Which is a more common formulation, and more likely to be supported.

    David


    David http://blogs.msdn.com/b/dbrowne/





    Tuesday, September 3, 2013 7:22 PM

All replies

  • Those two actually compile to identical code -

    You could try using Contains instead of Any - many of the LINQ providers can handle that:

    db.Table<JpFlashCard.Classes.Kana>().Where(a => ints.Contains(i => i == a.RowID));


    Reed Copsey, Jr. - http://reedcopsey.com - If a post answers your question, please click Mark As Answer on that post. If you find a post helpful, please click Vote as Helpful.

    Tuesday, September 3, 2013 7:19 PM
  • Those two queries are identical.  LINQ is just syntactic sugar for the pipeline of extension methods in the non-LINQ version.  The important thing is those are queries, and they are being interpreted by a provider and transformed into a source query.

    If the provider can't transform your query, you can send it simpler query, and then filter the results using LINQ 2 Objects

    Since your data is already in memory you can just write:

    db.Table<JpFlashCard.Classes.Kana>().AsEnumerable().Where(a => ints.Any(i => i == a.RowID));


    Methods like AsEnumerable(), ToList(), First(), FirstOrDefault() will actually execute the query and return a collection of objects, which can be further filtered and transformed.

    Also you can play with equivalent queries to see if you find one that will translate,

    db.Table<JpFlashCard.Classes.Kana>().Where(a => ints.Contains(a.RowId)) )

    Which is a more common formulation, and more likely to be supported.

    David


    David http://blogs.msdn.com/b/dbrowne/





    Tuesday, September 3, 2013 7:22 PM
  • Thanks! Using .Contains instead of .Any did the trick!

    Michael DiLeo

    Tuesday, September 3, 2013 7:39 PM