5

I have a class setup like this:

 public class Summary
{
    public Geometry geometry { get; set; }
    public SummaryAttributes attributes { get; set; }
}
public class SummaryAttributes
{
    public int SERIAL_NO { get; set; }
    public string District { get; set; }
 }
public class Geometry
{
    public List<List<List<double>>> paths { get; set; }
}

and i take a json string of records for that object and cram them in there like this:

List<Summary> oFeatures = reportObject.layers[0].features.ToObject<List<Summary>>();

my end goal is to create a csv file so i need one flat List of records to send to the csv writer i have. I can do this:

 List<SummaryAttributes> oAtts = oFeatures.Select(x => x.attributes).ToList();

and i get a nice List of the attributes and send that off to csv. Easy peasy.

What i want though is to also pluck a field off of the Geometry object as well and include that in my final List to go to csv. So the final List going to the csv writer would contain objects with all of the fields from SummaryAttributes plus the first and last double values from the paths field on the Geometry object (paths[0][0][first] and paths[0][0][last])

It's hard to explain. I want to graft two extra attributes onto the original SummaryAttributes object. I would be ok with creating a new SummaryAttributesXY class with the two extra fields if that's what it takes. But i'm trying to avoid creating a new anonymous object and having to delimit every field in the SummaryAttributes class as there are many more than i have listed in this sample.

Any suggestions?

VBAHole
  • 1,508
  • 2
  • 24
  • 38
  • Can you not make your csv writer to accept `List oFeatures` as parameter instead of `List oAtts`? Or perhaps dynamic properties are of interest to you: http://stackoverflow.com/questions/947241/how-do-i-create-dynamic-properties-in-c? – PJvG Mar 22 '17 at 15:51
  • 1
    interesting thought. I would rather not modify the csv writer to drill down into lists of objects. But that got me thinking that maybe i could get this done at the point where i deserialize the json, rather than in the linq query – VBAHole Mar 22 '17 at 16:01

2 Answers2

4

You can select new anonymous object with required fields, but you should be completely sure that paths has at least one item in each level of lists:

var query = oFeatures.Select(s => new {
  s.attributes.SERIAL_NO,
  s.attributes.District,
  First = s.geometry.paths[0][0].First(), // or [0][0][0]
  Last = s.geometry.paths[0][0].Last()   
}).ToList()
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • my real SummaryAttributes table has 30 fields in it. And i'm going to be making about 20 different incarnations of this pattern. Is there a way to avoid the anonymous type? – VBAHole Mar 22 '17 at 15:29
  • @VBAHole you can use some mapping library like AutoMapper to do mapping job for you, but you still need to define class with all flattened properties – Sergey Berezovskiy Mar 22 '17 at 15:32
1

Got it figured out. I include the X and Y fields in the original class definition. When the json gets deserialized they will be null. Then i loop back and fill them in.

 List<Summary> oFeatures = reportObject.layers[0].features.ToObject<List<Summary>>();
                List<Summary> summary = oFeatures.Select(s =>
                {
                    var t = new Summary
                    {
                        attributes = s.attributes
                    };
                    t.attributes.XY1 = string.Format("{0} , {1}", s.geometry.paths[0][0].First(), s.geometry.paths[0][1].First());
                    t.attributes.XY2 = string.Format("{0} , {1}", s.geometry.paths[0][0].Last(), s.geometry.paths[0][1].First());
                    return t;
                }).ToList();
                List<SummaryAttributes> oAtts = summary.Select(x => x.attributes).ToList();
VBAHole
  • 1,508
  • 2
  • 24
  • 38
  • Feel free to accept your own answer if this is the solution. Alternatively, you could also delete the whole question if you think it's not valuable to keep it around anymore. – PJvG Mar 23 '17 at 06:34