Welsh King
Welsh King

Reputation: 3238

Looping through a dynamic linq object with joins

I have the following function

 public List<Object> GetEventsForAdmin()
    {
        using (var dbEntities = new CapeledEntities())
        {
            return (from e in dbEntities.Events
                    join lnk in dbEntities.linkEventCategories on e.EventId equals lnk.EventId
                    join cat in dbEntities.Categories on lnk.CategoryId equals cat.CategoryId
                    orderby e.StartDateTime descending
                    select new { 
                                    e.EventId, 
                                    EventTitle =  e.Title,
                                    e.StartDateTime,
                                    e.Description, 
                                    CatTitle = cat.Title 
                   }
            ).ToList<Object>();
        }
    }

I am using

  var eventHelper = new BusinessLogic.DatabaseAccess.Helpers.BLEvents();
  foreach (var myEvent in eventHelper.GetEventsForAdmin())
  {
       txtTitle.text = myEvent.CatTitle;
       txtDescription.text = myEvent.description;
   }

However myEvent.CatTitle and myEvent.description are not found argh

  }

Upvotes: 1

Views: 770

Answers (3)

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73482

It seems there are three possible ways as far as I know.

1) Use Dynamic (requires .Net 4.0 or higher)

foreach (dynamic myEvent in eventHelper.GetEventsForAdmin())

2) Create your own type(perhaps a class) instead of anonymous type

3) Third one is a tricky one which uses CastByExample which you can find here

object obj = eventHelper.GetEventsForAdmin();
var events = CastByExample(obj, new[] { 
                                    new { EventId = 0, 
                                          EventTitle = "",
                                          StartDateTime = DateTime.MinValue,
                                          Description = "", 
                                          CatTitle = ""
                                        }
                                      }.ToList());
foreach (var item in events)
{
    Console.WriteLine(item.EventId);
}

private static T CastByExample<T>(object obj, T example)
{
    return (T)obj;
}

4) As @KingKing suggested in comments I missed Reflection you can do that via reflection too, but that's not a good idea to this problem.

Being said that as many methods available, I'll suggest method 2 which is the ideal solution to this problem.

Upvotes: 1

dotNET
dotNET

Reputation: 35400

Instead of using dynamic, I'd suggest you create a simple struct or class like this:

class Event
{ 
    public int EventId;
    public string EventTitle;
    public DateTime StartDateTime;
    public string Description;
    public string CatTitle;
}

Now instead of doing select new in your LINQ, you can create a well-defined type that will give you coding advantages as well as performance boost becuz no boxing/unboxing will be involved.

Your LINQ would then be:

public List<Event> GetEventsForAdmin()
{
    using (var dbEntities = new CapeledEntities())
    {
        return (from e in dbEntities.Events
                join lnk in dbEntities.linkEventCategories on e.EventId equals lnk.EventId
                join cat in dbEntities.Categories on lnk.CategoryId equals cat.CategoryId
                orderby e.StartDateTime descending
                select new Event() { 
                                .EventId = e.EventId, 
                                .EventTitle = e.Title,
                                .StartDateTime = e.StartDateTime,
                                .Description = e.Description, 
                                .CatTitle = cat.Title 
               }
        ).ToList();
    }
}

Upvotes: 2

Baldrick
Baldrick

Reputation: 11840

Change

foreach (var myEvent in eventHelper.GetEventsForAdmin())

to

foreach (dynamic myEvent in eventHelper.GetEventsForAdmin())

This should allow you to access members of an anonymous type which has been cast as an object.

Upvotes: 2

Related Questions