2016-02-10 16 views
6

Używam LINQ z Entity framework do łączenia trzech tabel i wracam interfejs IList.foreach na IEnumerable lub IList

Chcę zastosować pętlę foreach dla zwróconej wartości, aby można było wypełniać wartości w moim modelu.

To jak mam łączenie:

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(); 
} 

Chcę, aby wypełnić te wartości w mojej listy Model. Próbowałem to:

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

} 

Ale jestem w stanie uzyskać dostęp artykuł Firstname/Lastname itp

Próbowałem też za pomocą obiektu item i object[] item ale oboje nie pracują zbyt.

W jaki sposób mogę zastosować for dla każdego IL-1-a?

Będzie działać dobrze, jeśli będę w stanie zwrócić DataTable zamiast IList w tym przypadku.

Odpowiedz

7

Twój tworzą typ anonimowy. Wystarczy zdefiniować klasę dla wyniku zapytania, a następnie zwracany typ swojej funkcji powinno być tak:

public IList<YourClassName> GetData(long Id) 
{ 

} 

wartości klasy Ustaw tak:

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

Tworzycie typ anonimowy:

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

Jeśli chcesz przekazać te dane do innych metod itd. Trzeba stworzyć prawdziwą klasę.

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; } 
} 

i używać go:

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

Używasz typ anonimowy więc nie możesz rzucić go do niczego, gdy przeglądasz listę. Można spróbować użyć dynamic zamiast var który oznacza, że ​​można wywołać dowolną nieruchomość na nim tak długo, jak istnieje w czasie wykonywania:

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

lub jednoznacznie określające klasę dla elementu wyniku jak inne odpowiedzi sugeruje.

0

Należy zmienić typ zwrotu na GetData. Spróbuj:

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

Powinieneś zwrócić nie tylko interfejs IList, ale sparametryzować interfejs ze swoim typem. Teraz retainint anounymouse obiektu.

To, co chcę zasugerować.Tworzenie tej klasy:

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; } 
} 

I zmienić metodę tak:

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(); 
     } 

Teraz powrocie nie Anonymouse obiekt wewnątrz listy, dzięki czemu można uzyskać wszystkie właściwości potrzebne

4

Wracasz w metodzie anonymous lista objects. Możesz uzyskać dostęp do właściwości za pomocą refleksji, ale w środowisku uruchomieniowym jest to powolne. Najłatwiejszym sposobem uzyskania informacji o typie jest zdefiniowanie klasy i użycie jej w instrukcji 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(); 
}