2010-04-19 18 views
5

Mi línea es IQueryable:Linq filtrando un objeto IQueryable <T> (System.Data.Linq.DataQuery) por un objeto List <T> (System.Collection.Generic.List)?

// find all timesheets for this period - from db so System.Data.Linq.DataQuery 
var timesheets = _timesheetRepository.FindByPeriod(dte1, dte2); 

Mi línea de lista es:

// get my team from AD - from active directory so System.Collection.Generic.List 
var adUsers = _adUserRepository.GetMyTeam(User.Identity.Name); 

Deseo mostrar sólo hojas de tiempo para los usuarios de la colección de parte de horas que están presentes en la colección del usuario.

Si utilizo un # de expresión estándar C, tales como:

var teamsheets = from t in timesheets 
        join user in adUsers on t.User1.username equals user.fullname 
        select t; 

me sale el error "IQueryable que devuelve una expresión constante referencia a sí misma no es compatible"

¿Alguna recomendación?

+0

¿Qué tan grandes son los equipos? – SteadyEddi

+0

No más de 20 usuarios por equipo si eso - entonces .contains debería resistir – Klaptrap

Respuesta

3

La construcción de unión no funcionará, pero puede usar el enfoque Contains. Este próximo fragmento podría hacer el truco.

string[] usernames = adUsers.Select(u => u.fullname).ToArray(); 

var teamsheets = 
    from t in timesheets 
    where usernames.Contains(t.User1.username) 
    select t; 
+0

Cracked it - gracias – Klaptrap

4

Linq to Sql intentará generar una consulta SQL para representar toda la expresión. Esto significa que intentará pasar la colección de usuarios de anuncios como parámetros a una consulta SQL. Si hay demasiados usuarios, la consulta alcanzará el límite del parámetro (2100) y no se podrá ejecutar. Si no hay tantos usuarios en un equipo, puede usar una expresión contiene que se convertirá en una expresión "IN" en sql.

Esto es lo que Steven ha sugerido:

string[] usernames = adUsers.Select(u => u.fullname).ToArray(); 

var teamsheets = 
from t in timesheets 
where usernames.Contains(t.User1.username) 
select t; 

La única manera de utilizar una combinación en la forma en que ha intentado sería para recuperar toda la tabla de tiempos de la base de datos en la memoria (usando ToList en el timesheets var), y luego la unión ocurrirá en la memoria. Si esto funciona mejor que usar Contiene, o no puede usar Contiene debido al tamaño del equipo, podría valer la pena considerarlo.

+0

Gracias por la explicación adicional - todo tiene sentido bajo una luz diferente. – Klaptrap

Cuestiones relacionadas