Khadim Ali
Khadim Ali

Reputation: 2598

Subquery in Where Clause of LINQ statement

So I tried to follow this example to have a sub-query in the where clause of this LINQ query.

var innerquery =
    from app in context.applications
    select new { app.app_id };

IEnumerable<postDatedCheque> _entityList = context.postDatedCheques
    .Where(e => innerquery.Contains(e.appSancAdvice.application.app_id));

The objective was to select those records from postDatedCheques that have app_id in applications table.

But I am getting following erros inside the where clause:

  1. Delegate 'System.Func' does not take 1 arguments
  2. Cannot convert lambda expression to type 'string' because it is not a delegate type
  3. 'System.Linq.IQueryable' does not contain a definition for 'Contains' and the best extension method overload 'System.Linq.ParallelEnumerable.Contains(System.Linq.ParallelQuery, TSource)' has some invalid arguments
  4. Instance argument: cannot convert from 'System.Linq.IQueryable' to 'System.Linq.ParallelQuery'

What am I coding incorrect?

Upvotes: 1

Views: 27076

Answers (4)

Askolein
Askolein

Reputation: 3378

I think a simple join would do the job. It will filter out the 'cheques' that have no relative 'app':

  var _entitylist = 
    from cheque in context.postDatedCheques
    join app in context.applications on cheque.appSancAdvice.application equals app
    select cheque;

Edit:

Solutions using a .Contains(...) will be translated into a SQL IN statement. Which will be very inefficient. Linq join is translated into SQL INNER JOIN which is very efficient if your DB schema is well trimmed (FKs, index)

Upvotes: 5

roybalderama
roybalderama

Reputation: 1640

Try this instead:

var innerquery =
    from app in context.applications
    select new { app.app_id };

IEnumerable<postDatedCheque> _entityList = context.postDatedCheques
    .Where(e => innerquery.Any(a => a.app_id == e.appSansAdvice.application.app_id));

Upvotes: 1

Bob Vale
Bob Vale

Reputation: 18474

What about?

IEnumerable<postDatedCheque> _entityList = context.postDatedCheques.Where(
     e => context.applications.Any(
          x => e.appSancAdvice.application.app_id == x.app_id));

And if you want to use two statements, set the first as an expression function.

Expression<Func<string, bool>> innerQuery = 
          x => context.applications.Any(y => y.app_id == x);

IEnumerable<postDatedCheque _entityList = 
  context.postDatedCheques.Where(
    x => innerQuery(x.appSancAdvice.application.app_id));

Upvotes: 5

Cyril Gandon
Cyril Gandon

Reputation: 17068

innerquery is a IQueryable of anonymous type that contains an app_id.
The line Contains(e.appSancAdvice.application.app_id) doesn't make sense since e.appSancAdvice.application.app_id and the anonymous type are not the same type.

Simply do:

var _entityList = context.postDatedCheques
                         .Where(e => 
                            context.applications
                                   .Select(a => a.app_id)
                                   .Contains(e.appSancAdvice.application.app_id));

Upvotes: 2

Related Questions