tags:

views:

41

answers:

1

Hello, I have no firm idea how to word this question, so forgive me if I don't use the correct terminology.

I have a System.Xml.Linq.XElement el which contains an xml document. I want to query a part of the XElement and add user objects (Upload) to a generic list (UploadList held in a page property) like so:

this.UploadsList.Add((from el1 in el.Descendants("Uploads")
                                      select new Upload
                                      {
                                          Comments = el1.Element("Comments") != null ? el1.Element("Comments").Value : ""
                                          , 
                                          ***ConsentForImageUse.Text=el1.Element("SomeNode") != null ? el1.Element("SomeNode").Value : ""***
                                          ,
                                          DateImageProduced = el1.Element("DateImageProduced").Value != "" ? DateTime.Parse(el1.Element("DateImageProduced").Value) : DateTime.MinValue
                                          ,
                                          ImageTakenBy = el1.Element("ImageTakenBy") != null ? el1.Element("ImageTakenBy").Value : ""
                                      }).First<Upload>());

The compiler complains about the bit with the asterisks.

My Upload object has a property ConsentForImageUse which is itself a class with a couple of properties.

The error is Invalid initialiser member declarator. Does anyone know if I can create 'complex' objects using Linq like this like this?

+2  A: 

Because of the way that object initializers are specified, you cannot set a property of a property in one. Instead, create an your ConsentForImageUse object as a let binding in your LINQ query, and assign that to the Upload object's ConsentForImageUse property. Without further knowledge of your precise object model, I've made some assumptions, but this ought to work for you.

var uploads = from el1 in el.Descendants("Uploads")
              let consent = new ConsentForImageUse() { Text = el1.Element("SomeNode") != null ? el1.Element("SomeNode").Value : string.Empty }
              select new Upload
              {
                  Comments = el1.Element("Comments") != null ? el1.Element("Comments").Value : string.Empty,
                  ConsentForImageUse = consent,
                  DateImageProduced = el1.Element("DateImageProduced") != null ? el1.Element("DateImageProduced").Value : string.Empty,
                  ImageTakenBy = el1.Element("ImageTakenBy") != null ? el1.Element("ImageTakenBy").Value : string.Empty
              };

list.Add(uploads.First());
Ben
No need to use `let` really. You can move that whole bit of code where `consent` is. Either way works.
Ahmad Mageed
For me, the `let` is an aesthetic choice. I tend to regard overly-long object initializers as ungainly. You're right, though - it will work either way.
Ben
That looks promising - I'll give it a go in the morning - thanks!
adrianos
Outstanding - works a treat! Thanks very much for your help!
adrianos