0

I'm loading XML data into an object with this LINQ statement:

var smartFormFields = from smartFormField in xmlDoc.Descendants("smartFormField")
                      select new Models.SmartFormField
                      {
                          IdCode = smartFormField.Element("idCode").Value,
                          Label = smartFormField.Element("label").Value,
                          FieldType = smartFormField.Element("fieldType").Value,
                          DisplayStatus = smartFormField.Element("displayStatus").Value,
                          RequiredStatus = smartFormField.Element("requiredStatus").Value,
                          DisplayColumn = (int)smartFormField.Element("displayColumn"),
                          DisplayOrder = (int)smartFormField.Element("displayOrder"),
                          Description = smartFormField.Element("description").Value,
                          Example = smartFormField.Element("example").Value,
                          ControlType = smartFormField.Element("controlType").Value,
                          AutoSuggestDataSource = smartFormField.Element("autoSuggestDataSource").Value
                      };

However, my WHERE (and ORDERBY) statement will change each time, e.g.

it may be this:

var smartFormFields = from smartFormField in xmlDoc.Descendants("field")
                      where smartFormField.Element("IdCode").Value == "lastName"
                      select new Models.SmartFormField
                      {...

it may be this:

var smartFormFields = from smartFormField in xmlDoc.Descendants("field")
                      where (int)smartFormField.Element("DisplayOrder").Value > 50
                      select new Models.SmartFormField
                      {...

etc.

How can I put the Where statement into a variable, something like this:

PSEUDO-CODE:

string whereStatement = "where (int)smartFormField.Element(\"DisplayOrder\").Value > 50";

var smartFormFields = from smartFormField in xmlDoc.Descendants("field")
                      &&whereStatement
                      select new Models.SmartFormField
                      {...
Pablo Fernandez
  • 279,434
  • 135
  • 377
  • 622
Edward Tanguay
  • 189,012
  • 314
  • 712
  • 1,047

1 Answers1

3

Do you have to express it as a string? If you're happy to supply it as a delegate, you can use:

// Just as one example of a where clause
Func<XElement, bool> whereClause = sff => (int) sff.Element("DisplayOrder").Value > 50;

var smartFormFields = xmlDoc.Descendants("field")
                            .Where(whereClause)
                            .Select(sff => 
                                new Models.SmartFormField
                                {
                                    IdCode = sff.Element("idCode").Value,
                                    ...
                                });

If you put this into a method, then you just need to use a lambda expression:

var fields = GetFormFields(sff => (int) sff.Element("DisplayOrder").Value > 50);

etc

That will let you easily supply different values for different calls, but you won't be able to just put the expressions into a text file without a bit more work. What are your real requirements here? Could you have a map of "filter name" to Func<XElement, bool>, and then read the filter names at execution time? Or do you really need it to be fully controlled at execution time, in an arbitrary way?

(Note that ordering is similar but probably slightly trickier... let's get the filtering sorted first.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • very interesting, requirements are: be able to parse various "load codes" from the constructor to load various groups from the XML file, so I will just have a switch statement that converts text into delegates, let build try to build this in... – Edward Tanguay Jun 09 '09 at 12:24
  • I'd just have a Dictionary> and use that rather than a switch statement. – Jon Skeet Jun 09 '09 at 12:45
  • though it is not my post but still i like to request u to post a full small working sample of using string in LINQ like `xmlDoc.Descendants("field") .Where(whereClause)` – Thomas Jul 21 '15 at 19:53
  • @Thomas: Well what more do you need than is in there? The `...` would just be a lambda expression. – Jon Skeet Jul 21 '15 at 20:12
  • the `where delegate function code` is not completed. i need to see how where delegate code would look like..because i am not familiar with that kind of where clause. thanks – Thomas Jul 22 '15 at 07:55
  • @Thomas: Well the final part showed an example... but I've changed the `...` to an example lambda expression... – Jon Skeet Jul 22 '15 at 08:04
  • thanks, we could write this way whole thing....then why u use delegate function as separate one...any special reason was there ? `var smartFormFields = xmlDoc.Descendants("field") .Where(e=> e.Element("DisplayOrder").Value > 50) .Select(sff => new Models.SmartFormField { IdCode = sff.Element("idCode").Value, ... });` – Thomas Jul 22 '15 at 11:10
  • @Thomas: The point is that the OP wants to pass the delegate into the method, or perhaps choose between multiple different options within the same method. – Jon Skeet Jul 22 '15 at 11:44
  • @JonSkeet Thanks for your reply :) – Thomas Jul 22 '15 at 13:36