esteban
esteban

Reputation: 63

Exception: Type arguments cannot be inferred when using LINQ

I've got this query that works ok,

select *
from Materia 
where
  Cursar_Cursada=0
  and idmateria NOT IN (
      select IdMateria
      from UsuarioMateria
      where IdUsuario=11
  ) 
  or Cursar_Cursada in (
    select Materia.Codigo_Materia
    from UsuarioMateria join Materia on UsuarioMateria.IdMateria = Materia.IdMateria
  )

When I try to create a LINQ for the same purpose I do not get the expected result.

 from t in obj.Materias
 where
   t.Cursar_Cursada == 0 &&
   !(from t0 in obj.UsuarioMaterias
     where
       t0.IdUsuario == 11
     select new
     {
         t0.IdMateria
     }).Contains(new { t.IdMateria }) ||

     (from t0 in obj.UsuarioMaterias
      join t1 in obj.Materias on t0.IdMateria equals      IdMateria
      select new
      {
          t1.Codigo_Materia
      }).Contains(new { t.Cursar_Cursada })   // <- error here
 select new
 {
     t.IdMateria,
     t.Nombre,
     t.Cuatrimestre,
     t.Contenido,
     t.Cursar_Cursada,
     t.Cursar_Aprobada,
     t.Rendir_Aprobada,
     t.Codigo_Materia
 };

the error is on the line that says .Contains(new { t.Cursar_Cursada }) and it says:

The type arguments for method 'System.Linq.Enumerable.Contains<TSource>(System.Collections.Generic.IEnumerable<TSource>, TSource)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

Upvotes: 2

Views: 3926

Answers (1)

Douglas
Douglas

Reputation: 54927

You don’t need to instantiate a single-property anonymous type each time to perform a Contains check. Instead, you should select your property directly:

from t in obj.Materias
where t.Cursar_Cursada == 0 &&
!(  
    from t0 in obj.UsuarioMaterias
    where t0.IdUsuario == 11
    select t0.IdMateria
).Contains(t.IdMateria) ||
(   
    from t0 in obj.UsuarioMaterias
    join t1 in obj.Materias on t0.IdMateria equals t1.IdMateria
    select t1.Codigo_Materia
).Contains(t.Cursar_Cursada)
select new
{
    t.IdMateria,
    t.Nombre,
    t.Cuatrimestre,
    t.Contenido,
    t.Cursar_Cursada,
    t.Cursar_Aprobada,
    t.Rendir_Aprobada,
    t.Codigo_Materia
};

Alternatively, you can convert your Contains operators to Any by including the equality check as a condition within your inner query:

from t in obj.Materias
where t.Cursar_Cursada == 0 &&
!(
    from t0 in obj.UsuarioMaterias
    where t0.IdUsuario == 11 && 
          t0.IdMateria == t.IdMateria
    select t0
).Any() ||
(   
    from t0 in obj.UsuarioMaterias
    join t1 in obj.Materias on t0.IdMateria equals t1.IdMateria
    where t1.Codigo_Materia == t.Cursar_Cursada
    select t1
).Any()
select new
{
    t.IdMateria,
    t.Nombre,
    t.Cuatrimestre,
    t.Contenido,
    t.Cursar_Cursada,
    t.Cursar_Aprobada,
    t.Rendir_Aprobada,
    t.Codigo_Materia
};

Upvotes: 1

Related Questions