0
\$\begingroup\$

I am trying to abstract data from a complex and create a EventDto. And I was able to do it using foreach but the syntax is dreadful. Is there a better way of writing this code?

 public class EventDtO
 {
    public string Id { get; set; }
    public string Title { get; set; }
    public string CategoryTitle { get; set; }
    public DateTime DateTime { get; set; }
  }

This is the complex object that I am trying to get the data from:

public class RootObject
{ 
    public List<Event> Events { get; set; }
}

public class Event
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string Link { get; set; }
    public List<Category> Categories { get; set; }
    public List<Geometry> Geometries { get; set; }
}

public class Geometry
{
    public DateTime Date { get; set; }
    public string Type { get; set; }
    public List<object> Coordinates { get; set; }
}

    public class Category 
{ 
    public int Id { get; set; }
    public string Title { get; set; }
}

The mapping relationship I want is

EventDto.Id->Event.Id
EventDto.Title->Event.Title
Event.CategoryTitle->Category.Title
Event.DateTime->Geometry.Date

The Category class will only contain one value, but the geometry.Date can have multiple values.

So the output I want is:

Title           Categories          Date    
"Iceberg B42"   Sea and Lake Ice    2020-04-23T14:24:00Z    
"Iceberg B42"   Sea and Lake Ice    2017-09-15T00:00:00Z

I am able to get the correct information if I use the following code:

var Event = new List<EventDTO>();
foreach (var con in content.Events)
{
    var data = new EventDTO
    {
        Title = con.Title,
        Id = con.Id
    };

    foreach (var cat in con.Categories)
    {
        data.CategoriesTitle = cat.Title;
    }

    foreach (var geo in con.Geometries)
    {
        data.DateTime = geo.Date;
        Event.Add(data);
    }
}

An example of the JSON:

   {
        "id": "EONET_2881",
        "title": "Iceberg B42",
             "description": "",
        "categories": [
            {
                "id": 15,
                "title": "Sea and Lake Ice"
            }
        ]
        "geometries": [
            {
                "date": "2017-04-21T00:00:00Z",
                "type": "Point", 
                "coordinates": [ -107.19, -74.63 ]
            },
            {
                "date": "2017-09-15T00:00:00Z",
                "type": "Point", 
                "coordinates": [ -107.11, -74.08 ]
            }
        ]
    }
\$\endgroup\$

2 Answers 2

0
\$\begingroup\$

First of all, there is a bug in your example. In this loop:

foreach (var geo in con.Geometries)
{
    data.DateTime = geo.Date;
    Event.Add(data);
}

You are just overwriting date in the same object. You should create a new object instead. Your final list will have the same object twice with the same date.

As for better solution for this, you can use linq and create something like this:

IEnumerable<EventDTO> events = 
    from e in content.Events
    from c in e.Categories
    from g in e.Geometries
    select new EventDTO { Id = e.Id, Title = e.Title, CategoryTitle = c.Title, DateTime = g.Date };
\$\endgroup\$
0
\$\begingroup\$

This is the solution i went in the end

   var Event = content.Events.SelectMany(con => 
    con.Geometries.Select(geo => 
        new EventDTO
        {
            Title = con.Title,
            Id = con.Id,
            CategoriesTitle = con.Categories.FirstOrDefault().Title,
            DateTime = geo.Date
        })
    ).ToList();
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Always select your chosen answer even if you wrote it yourself. \$\endgroup\$
    – radarbob
    Commented May 26, 2020 at 14:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.