使LINQ-to-XML语句动态化的最佳方法是什么?

时间:2022-09-11 20:28:44

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

我正在使用此LINQ语句将XML数据加载到对象中:

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.

但是,我的WHERE(和ORDERBY)语句每次都会改变,例如

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:

如何将Where语句放入变量中,如下所示:

PSEUDO-CODE:

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

var smartFormFields = from smartFormField in xmlDoc.Descendants("field")
                      &&whereStatement
                      select new Models.SmartFormField
                      {...

1 个解决方案

#1


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:

如果将其放入方法中,则只需使用lambda表达式:

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?

这样可以让您轻松地为不同的调用提供不同的值,但是如果没有更多的工作,您将无法将表达式放入文本文件中。你有什么真正的要求吗?你有一个“过滤器名称”映射到Func ,然后在执行时读取过滤器名称吗?或者你真的需要它在执行时以任意方式完全控制吗? ,bool>

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

(注意,排序类似但可能稍微复杂一点......让我们首先对过滤进行排序。)

#1


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:

如果将其放入方法中,则只需使用lambda表达式:

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?

这样可以让您轻松地为不同的调用提供不同的值,但是如果没有更多的工作,您将无法将表达式放入文本文件中。你有什么真正的要求吗?你有一个“过滤器名称”映射到Func ,然后在执行时读取过滤器名称吗?或者你真的需要它在执行时以任意方式完全控制吗? ,bool>

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

(注意,排序类似但可能稍微复杂一点......让我们首先对过滤进行排序。)