Syed Salman Raza Zaidi
Syed Salman Raza Zaidi

Reputation: 2192

foreach on IEnumerable or IList

I am using LINQ with Entity framework to joining three tables and I am returning IList interface.

I want to apply foreach loop on this returned value so I can populate values in my model.

This is how I am joining:

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

I want to populate these values in my List of Model. I have tried this:

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

}

But I am unable to access item Firstname/Lastname etc.

I also tried using object item and object[] item but they both are not working too.

How can I apply a foreachonIList`?

It will work fine If I'm be able to return DataTable instead of IList in this case.

Upvotes: 5

Views: 3741

Answers (6)

user5069269
user5069269

Reputation:

You are creating an anonymous type. Just define a class for the result of your query, then the return type of your function should be like this:

public IList<YourClassName> GetData(long Id)
{

}

Finally set class values:

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

Upvotes: 7

Mark
Mark

Reputation: 1371

You're using an anonymous type so you can't cast it to anything when looping through your list. You could try using dynamic instead of var which means you can call any property on it as long as it exists at runtime:

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

or explicitly defining a class for the result item like the other answers are suggesting.

Upvotes: 0

ChrisF
ChrisF

Reputation: 137108

You are creating an anonymous type:

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

If you want to pass this data to other methods etc. you need to create a real class.

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

and use it:

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

Upvotes: 1

null
null

Reputation: 7926

You're returning an anonymous list of objects in the method. You can access the properties by using reflection but this is abit slow at runtime. Easiest to get type information is by defining a class and use that in the select statement.

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

Upvotes: 4

teo van kot
teo van kot

Reputation: 12491

You should return not just IList interface but parametrised interface with your type. Now you returtint anounymouse object.

So what i want to suggest. Create this class:

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

And the change your method like this:

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

Now you returning not anonymouse object within List so you can get all properties you need

Upvotes: 1

Alper Tunga Arslan
Alper Tunga Arslan

Reputation: 579

You must change GetData return type. Please try this:

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

Upvotes: 0

Related Questions