2016-02-10 12 views
6

Sto utilizzando LINQ con Entity framework per unire tre tabelle e restituisco l'interfaccia IList.foreach on IEnumerable o IList

Voglio applicare il ciclo foreach su questo valore restituito in modo da poter popolare i valori nel mio modello.

Questo è come mi sto unendo:

public IList GetData(long Id) 
{ 
    //var q = dataContext.tblUsers.AsEnumerable().Join(dataContext.tblUsersProfiles.AsEnumerable(),) 
    var query = from u in dataContext.tblUsers 
    join p in dataContext.tblUsersProfiles on u.ProfileId equals p.Id 
    join c in dataContext.tblComments on u.Id equals c.Commentedby 

    where c.Id == Id 
    select new { u.Firstname, u.Lastname, p.ProfilePicPath, c.Comment, c.CommentDate }; 

    return query.ToList(); 
} 

voglio compilare questi valori nella mia lista di modello. Ho provato questo:

var lst = repository.GetDate(Id); 
foreach (var item in lst) 
{ 

} 

Ma io sono in grado di accedere elemento Firstname/Lastname ecc

Ho anche provato ad utilizzare oggetto item e object[] item ma entrambi non si lavora troppo.

Come posso applicare un for ogni on IList`?

Funzionerà correttamente Se sono in grado di restituire DataTable anziché IList in questo caso.

risposta

7

tuo stanno creando un tipo anonimo. Basta definire una classe per il risultato della query, quindi il tipo di ritorno della funzione dovrebbe essere simile a questo:

public IList<YourClassName> GetData(long Id) 
{ 

} 

valori Set di classe in questo modo:

select new YourClassName 
{ 
    Firstname = u.Firstname, 
    Lastname = u.Lastname, 
    ProfilePicPath = p.ProfilePicPath, 
    Comment = c.Comment, 
    CommentDate = c.CommentDate 
}; 
1

Si sta creando un tipo anonimo:

select new { u.Firstname, u.Lastname, p.ProfilePicPath, c.Comment, c.CommentDate }; 

Se si desidera passare questi dati ad altri metodi, ecc è necessario creare una vera classe.

public class DataClass 
{ 
    public string Firstname { get; set; } 
    public string LastName{ get; set; } 
    public string ProfilePicPath { get; set; } 
    public string Comment { get; set; } 
    public DateTime CommentDate { get; set; } 
} 

e usarlo:

public IList<DataClass> GetData(long Id) 
{ 
    var query = from u in dataContext.tblUsers 
       join p in dataContext.tblUsersProfiles on u.ProfileId equals p.Id 
       join c in dataContext.tblComments on u.Id equals c.Commentedby 
       where c.Id == Id 
    select new DataClass 
    { 
     Firstname = u.Firstname, 
     Lastname = u.Lastname, 
     ProfilePicPath = p.ProfilePicPath, 
     Comment = c.Comment, 
     CommentDate = c.CommentDate 
    }; 

    return query.ToList(); 
} 
0

Stai usando un tipo anonimo quindi non puoi trasmetterlo a nulla quando esegui il ciclo di ricerca nell'elenco. Si potrebbe provare a utilizzare dynamic invece di var che significa che è possibile chiamare qualsiasi proprietà su di essa finché esiste in fase di esecuzione:

foreach (dynamic item in lst) 
{ 
    string firstName = item.FirstName; 
} 

o esplicitamente la definizione di una classe per l'oggetto risultato come le altre risposte suggeriscono.

0

È necessario modificare il tipo di ritorno GetData. Si prega di provare questo:

public List<tblUsers> GetData(long Id) 
     { 
      //var q = dataContext.tblUsers.AsEnumerable().Join(dataContext.tblUsersProfiles.AsEnumerable(),) 
      var query = from u in dataContext.tblUsers 
         join p in dataContext.tblUsersProfiles on u.ProfileId equals p.Id 
         join c in dataContext.tblComments on u.Id equals c.Commentedby 
         where c.Id == Id 
         select new tblUsers { u.Firstname, u.Lastname, p.ProfilePicPath, c.Comment, c.CommentDate }; 
      return query.ToList(); 
     } 
1

Si dovrebbe tornare non solo interfaccia IList ma interfaccia parametrizzata con il vostro tipo. Ora si returtint oggetto di unounymouse.

Quindi quello che voglio suggerire.Creare questa classe:

public class MyCustomContainer 
{ 
    public string Firstname { get; set; } 
    public string Lastname { get; set; } 
    public string ProfilePicPath { get; set; } 
    public string Comment { get; set; } 
    public string CommentDate { get; set; } 
} 

E il cambiamento tuo metodo come questo:

public IList<MyCustomContainer> GetData(long Id) 
     { 
      //var q = dataContext.tblUsers.AsEnumerable().Join(dataContext.tblUsersProfiles.AsEnumerable(),) 
      var query = from u in dataContext.tblUsers 
         join p in dataContext.tblUsersProfiles on u.ProfileId equals p.Id 
         join c in dataContext.tblComments on u.Id equals c.Commentedby 
         where c.Id == Id 
         select new MyCustomContainer 
         { 
          Firstname = u.Firstname, 
          Lastname = u.Lastname, 
          ProfilePicPath = p.ProfilePicPath, 
          Comment = c.Comment, 
          CommentDate = c.CommentDate 
          }; 
      return query.ToList(); 
     } 

Ora è il ritorno non Anonymouse oggetto all'interno di lista in modo da poter ottenere tutte le proprietà necessari

4

stai tornando un elenco anonymous di objects nel metodo. È possibile accedere alle proprietà utilizzando la reflection ma questo è un po 'lento durante l'esecuzione. È più facile ottenere informazioni sul tipo definendo una classe e utilizzarla nell'istruzione select.

public class Person 
{ 
    public string Firstname { get; set; } 
    public string Lastname { get; set; } 
    /* ... */ 
} 

public IList<Person> GetData(long Id) 
{ 
    var query = from u in dataContext.tblUsers 
       join p in dataContext.tblUsersProfiles on u.ProfileId equals p.Id 
       join c in dataContext.tblComments on u.Id equals c.Commentedby 
       where c.Id == Id 
       select new Person { u.Firstname, u.Lastname /* ... */ }; 
     return query.ToList(); 
} 
Problemi correlati