2

I am trying to build a Events Calendar, where i am getting the dates/events from an XML file in C#

I am loading my xml document through this:

XDocument myEventsDocument = XDocument.Load(Server.MapPath("Events.xml"));

Then I am storing the events in a variable :

 var resultSet = from p in myEventsDocument.Descendants("event")
                    select new
                    {
                        eventName = p.Attribute("title").Value,
                        eventVenue = p.Attribute("venue").Value,
                        eventDate = p.Attribute("date").Value,
                        eventTime = p.Attribute("time").Value,
                        eventDuration = p.Attribute("LengthOfEventInMts").Value
                    };

Then I am caching the entire results:

 Cache.Insert("eventsCache", resultSet, new CacheDependency(Server.MapPath("Events.xml")));

In the DayRender event of the Calendar class, I am storing the Cached result in a non-generic collection of IEnumeration:

IEnumerable itemCache = (IEnumerable)Cache["eventsCache"];

When i loop through the items in itemCache, I am not seeing the items in intellisense, but when i step-over while debugging, i am seeing the IEnumerable items.

screen shot in the code-behind

Here is the screen shot while stepping-through the code:

Please help me out where i am going wrong.

Ron
  • 1,901
  • 4
  • 19
  • 38

2 Answers2

2

You will need to create a simple class to access the members.

public sealed class EventInfo
{
    public string Name { get; set; }
    public string Venue { get; set; }
    public string Date { get; set; }
    public string Time { get; set; }
    public string Duration { get; set; }
}

Then you must evaluate the query.

var results = query.ToList().AsReadOnly();
Cache.Insert("eventsCache", results, 
    new CacheDependency(Server.MapPath("Events.xml")));

One you need the results you must cast to the proper type.

var itemCache = (IEnumerable<EventInfo>)Cache["eventsCache"];
ChaosPandion
  • 77,506
  • 18
  • 119
  • 157
  • Thanks ChaosPandion - I will keep this in mind for my future coding. I was able to achieve the results with less coding of implementing @p.s.w.g's solution of using 'dynamic'. I appreciate your help. – Ron Nov 20 '13 at 04:40
1

Unlike IEnumerable<T>, the IEnumerable interface does not assume the items being enumerated are of any particular type, so as far as intellisense is concerned, myItem is of type object. There are two options I see:

  1. Use a named type rather than an anonymous type:

    public class MyCacheItem { ... }
    
    var resultSet = 
        from p in myEventsDocument.Descendants("event")
        select new MyCacheItem { ... }
    
    IEnumerable<MyCacheItem> itemCache = (IEnumerable<MyCacheItem>)Cache["eventCache"];
    
  2. Use dynamic to iterate over the set. This won't give you intellisense, but it will allow your code to compile:

    foreach(dynamic myItem in itemCache)
    {
        ...
    }
    
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • Thanks @p.s.w.g I tried your solution of using 'dynamic' and worked well. Learnt something new today. Appreciate it. – Ron Nov 20 '13 at 04:38
  • @Ron Glad I could help. I would caution, however, that using `dynamic` is a little bit of a hack, and overusing it can have a significant performance impact and worse, make your code hard to maintain. There's nothing *wrong* with the solution, but I recommend you try the other solution first. – p.s.w.g Nov 20 '13 at 04:42
  • @Ron - `dynamic` is a powerful feature that can easily be misused. Make sure you carefully analyze whatever circumstances you are in each time before using it. – ChaosPandion Nov 20 '13 at 04:44
  • Thanks @p.s.w.g & ChaosPandion for the alert. Will keep that in mind, and use it accordingly.!! Much Thanks !! – Ron Nov 20 '13 at 04:53
  • @p.s.w.g i tried the 1st solution, using named type and works flawlessly. & Thanks to ChaosPandian, as well, for suggesting similar solutions. – Ron Nov 20 '13 at 05:09