2010-04-19 11 views
5

La mia linea è IQueryable:Linq che filtra un oggetto IQueryable <T> (System.Data.Linq.DataQuery) da un oggetto 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); 

La mia linea List è:

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

desidero per mostrare solo schede per gli utenti della collezione scheda attività che sono presenti nella collezione utente.

Se io uso un C# espressione standard, come:

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

ottengo l'errore "Un IQueryable che restituisce un autoreferenziale espressione costante non è supportato"

Tutti i consigli?

+0

Quanto sono grandi le squadre? – SteadyEddi

+0

Non più di 20 utenti per squadra se questo - così .contains dovrebbe contenere – Klaptrap

risposta

3

Il costrutto di join non funziona, ma è possibile utilizzare l'approccio Contains. Questo snippet successivo potrebbe fare il trucco.

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 - grazie – Klaptrap

4

Linq to Sql tenterà di generare una query sql per rappresentare l'intera espressione. Ciò significa che proverà a passare nella raccolta di utenti pubblicitari come parametri per una query sql. Se ci sono troppi utenti, la query raggiungerà il limite del parametro (2100) e non potrà essere eseguita. Se non ci sono molti utenti in una squadra, allora puoi usare un'espressione contiene che verrà convertita in un'espressione "IN" in sql.

Questo è ciò che Steven ha suggerito:

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

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

L'unico modo per utilizzare un join nel modo in cui si è tentato sarebbe quello di recuperare tutti alla classifica dal database in memoria (utilizzando ToList sulla timesheets var), e quindi il join avverrà in memoria. Se ciò si comporta meglio dell'utilizzo di Contiene, o non è possibile utilizzare Contiene a causa delle dimensioni della squadra, questo potrebbe essere utile.

+0

Grazie per la spiegazione aggiuntiva - tutto ha senso in una luce diversa. – Klaptrap

Problemi correlati