{"id":5553,"date":"2007-08-29T18:51:00","date_gmt":"2007-08-29T18:51:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2007\/08\/29\/implementing-dynamic-searching-using-linq\/"},"modified":"2024-07-05T14:41:30","modified_gmt":"2024-07-05T21:41:30","slug":"implementing-dynamic-searching-using-linq","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/implementing-dynamic-searching-using-linq\/","title":{"rendered":"Implementing Dynamic Searching Using LINQ"},"content":{"rendered":"<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\"><span>A common requirement in forms-over-data applications is that users be able to search by any combination of fields to construct a dynamic query at run time.&nbsp; For example, the search feature in this application allows the user to find all records that meet criteria defined on multiple columns:<\/span><span><\/span><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><\/span><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/08\/DynamicLinq1.bmp\"><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\"><span>LINQ makes it easy to write powerful queries like this over various data sources; for instance, we can use the following query to find all Orders shipped to<\/span><span> a given country within a user-specified timeframe<\/span>:<\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> query = <span>From<\/span> order <span>In<\/span> db.Orders _<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Where<\/span> order.ShipCountry = <span>txt<\/span>C<span>oun<\/span>try.Text _<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>And<\/span> order.ShippedDate &gt;= <span>dtpStartDate.Value<\/span> _<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>And<\/span> order.ShippedDate &lt;= <span>dtpEndDate.Value<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">This is easy at compile-time, but what if we want to check the date the order was <i>entered <\/i>instead of the date it was shipped?&nbsp; In this case we\u2019d have to write a separate query using order.OrderDate.&nbsp; Doing this dynamically at runtime isn\u2019t all that difficult if you\u2019re just building up a SQL string, but how would we do this with LINQ?&nbsp; Doesn\u2019t LINQ require me to&nbsp;specify the criteria at compile time in order to construct the query?&nbsp; Fortunately the answer\u2019s no, LINQ supports constructing dynamic queries at runtime through the Expression Tree API and the Expression Compiler.<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p><span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\"><span>In Visual Studio 2008, any valid VB expression can be represented as an expression tree.&nbsp; What we need to do is create an Expression Tree to represent the user\u2019s criteria, and then pass it to the LINQ to SQL runtime to do the SQL translation.&nbsp; So for the first part of our Where clause above it\u2019d look something like this:<\/span><\/font><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> p = Expression.Parameter(<span>GetType<\/span>(Order), <span>&#8220;&#8221;<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> order = <span>GetType<\/span>(Order).GetProperty(<span>&#8220;ShipCountry&#8221;<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> expr = Expression.Equal(Expression.PropertyOrField(p, order.Name), Expression.Constant(<span>&#8220;Germany&#8221;<\/span>))<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> predicate = Expression.Lambda(<span>Of<\/span> Func(<span>Of<\/span> Order, <span>Boolean<\/span>))(expr, <span>New<\/span> ParameterExpression() {p})<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&gt;<span>Yikes, that\u2019s a mouthful\u2026and we\u2019ve only done 1\/3 of the Where clause so far<\/span><span>!&nbsp; I definitely don\u2019t want to write 12 lines just to construct a Where clause at runtime.&nbsp; What I\u2019d like to be able to do is write an extension method called CreateCondition that would allow me to construct the expression tree<\/span> in one easy line, something like this:<\/font><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> condition1 = db.Orders.CreateCondition(<span>&#8220;ShipCountry&#8221;<\/span>, Compare.Equal, <span>&#8220;Germany&#8221;<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">And then for ShippedDate we could make these two conditions:<\/font><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> startDate? = #1\/1\/1997#<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> endDate? = #1\/31\/1997#<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> condition2 = db.Orders.CreateCondition(<span>&#8220;ShippedDate&#8221;<\/span>, Compare.GreaterThanOrEqual, startDate)<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> condition3 = db.Orders.CreateCondition(<span>&#8220;ShippedDate&#8221;<\/span>, Compare.LessThanOrEqual, endDate)<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\"><span>(Note: There\u2019s a similar sample in Beta2 called<\/span><span> <\/span><span>DynamicQueries which does a lot more than what we\u2019re looking at here; think of this as an easier-to-write subset of DynamicQueries).<\/span><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\"><span>Notice that we passed in a String the first time, and a Nullable D<\/span>ate literal for the next two; we can do this because the CreateCondition method is generic and infers the type based on the parameter passed in.&nbsp; We now need to combine the conditions into one big condition:<\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> c = Condition.Combine(condition1, Compare.And, condition2, condition3)<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\"><span>Or we could take advantage of Operator Overloading and do it this way<\/span><span> <\/span><span>(equivalent to the line above):<\/span><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> c = condition1 <span>And<\/span> condition2 <span>And<\/span> condition3<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">Ok so now that we\u2019ve constructed our Condition object, let\u2019s use it to filter the data:<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>&#8216;Filter out all Orders that don&#8217;t match the Condition<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>&#8216;Note that the query isn&#8217;t&nbsp;executed yet to due to deferred execution<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> filteredQuery = db.Orders.Where(c)<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>&#8216;We can now perform&nbsp;other operations (such as Order By) on filteredQuery<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> query = <span>From<\/span> row <span>In<\/span> filteredQuery _<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Order<\/span> <span>By<\/span> row.OrderDate, row.OrderID _<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Select<\/span> row<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>&#8216;Executes the query and displays the results in DataGridView1<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataGridView1.DataSource = query<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">So far so good, we\u2019re using LINQ over a dynamicall<span>y-constructed<\/span> condition and everything\u2019s strongly-typed.&nbsp; <span>We\u2019re still only hitting the database once since deferred execution ensures the query doesn\u2019t run until we actually enumerate the results (through databinding). &nbsp;<\/span>The Condition API has made it a lot easier to construct and compile the expression trees, but we\u2019d still have to write a fair bit of code to construct these conditions based on user input.&nbsp; That\u2019s where the ConditionBuilder control comes in:<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\"><\/font>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span><\/span><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/span><span>&nbsp;<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/08\/DynamicLinq2.bmp\"><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">This allows the user to dynamically specify the criteria at runtime:<\/font><\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/08\/DynamicLinq1.bmp\"><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Notice that for Date fields we automatically get a DateTimePicker instead of a TextBox, and Booleans would result in a CheckBox.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Ok so we\u2019ve covered what the user experience is at runtime, but how do we actually create the Condition API?&nbsp; There\u2019s a fair bit of documentation in the code below so I won\u2019t go through all of it, but here\u2019s the basics:<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">1.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">There are three main classes: Condition, Condition(Of T), and Condition(Of T, S)<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">a.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Condition is an abstract class that is used to construct the generic versions.&nbsp; By structuring it this way we get the benefits of generic type parameter inference \u2013 i.e. we don\u2019t have to worry about passing the generic type parameters to the method; the factory method figures it out for us.<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">b.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Condition(Of T) is used to join multiple conditions together.&nbsp; T is the element type (i.e. Order in the example above).<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">c.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Condition(Of T, S) is the simplest type; it represents an \u201cobject.propery &lt;comparison&gt; value\u201d expression.&nbsp; The type parameter S will be inferred to be the type of the value passed in (i.e. String, Date, Boolean etc\u2026).<\/font><\/p>\n<p class=\"MsoListParagraph\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">2.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">For local execution of a query we compile the LambdaExpression to a delegate so that it can be executed in-memory.&nbsp; The user can invoke this delegate by calling the Matches method.<\/font><\/p>\n<p class=\"MsoListParagraph\"><span>&#8216;Compile the lambda expression into a delegate<\/span><\/p>\n<p class=\"MsoListParagraph\"><span>del = <span>DirectCast<\/span>(LambdaExpr.Compile(), Func(<span>Of<\/span> T, <span>Boolean<\/span>))<\/span><\/p>\n<p class=\"MsoListParagraph\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">3.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">The extension methods at the bottom are defined on IQueryable(Of T) for remote execution, and IEnumerable(Of T) for local execution.<\/font><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">The complete solution is attached in the file DynamicCondition.zip below, <i>note that you\u2019ll need to update the ConnectionString in app.config to point to your version of Northwind.<\/i><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><span lang=\"EN\"><\/span><\/span>&nbsp;<\/p>\n<p><span><span lang=\"EN\"><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Imports<\/span><span lang=\"EN\"> System.ComponentModel<\/span><span><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Imports<\/span><span lang=\"EN\"> System.Linq.Expressions<\/span><span><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Imports<\/span><span lang=\"EN\"> System.Runtime.CompilerServices<\/span><span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Module<\/span><span lang=\"EN\"> DynamicQuery<\/span><span><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">MustInherit<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Class<\/span><span lang=\"EN\"> Condition<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;Used to ensure we get the same instance of a particular ParameterExpression<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;across multiple queries<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Private<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Shared<\/span><span lang=\"EN\"> ParamTable <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">New<\/span><span lang=\"EN\"> Dictionary(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">String<\/span><span lang=\"EN\">, ParameterExpression)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;The expression tree which will be passed to the LINQ to SQL runtime<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Protected<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Friend<\/span><span lang=\"EN\"> LambdaExpr <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> LambdaExpression<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;Enumerates all the different comparisons which can be performed<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Enum<\/span><span lang=\"EN\"> Compare<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>[Or] = ExpressionType.Or<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;[And] = ExpressionType.And<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;[Xor] = ExpressionType.ExclusiveOr<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;[Not] = ExpressionType.Not<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;Equal = ExpressionType.Equal<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;[Like] = ExpressionType.TypeIs + 1<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;NotEqual = ExpressionType.NotEqual<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; [OrElse] = ExpressionType.OrElse<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; [AndAlso] = ExpressionType.AndAlso<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; LessThan = ExpressionType.LessThan<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; GreaterThan = ExpressionType.GreaterThan<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; LessThanOrEqual = ExpressionType.LessThanOrEqual<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; GreaterThanOrEqual = ExpressionType.GreaterThanOrEqual<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Enum<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;Constructs a Condition with T as the element type and S as the value&#8217;s type<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Shared<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\"> Create(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T, S)(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> dataSource <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> IEnumerable(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T), _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> propertyName <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">String<\/span><span lang=\"EN\">, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> condType <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Compare, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> value <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> S) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T, S)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>Return<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">New<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T, S)(propertyName, condType, value)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;Constructs a Condition with T as the element type and valueType as the value&#8217;s type<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;This is useful for situations where you won&#8217;t know the value&#8217;s type until runtime.<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Shared<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\"> Create(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> dataSource <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> IEnumerable(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T), _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> propertyName <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">String<\/span><span lang=\"EN\">, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> condType <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Compare, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> value <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Object<\/span><span lang=\"EN\">, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> valueType <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Type) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>Return<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">New<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)(propertyName, condType, value, valueType)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8221;&#8217; <\/span><span lang=\"EN\">&lt;summary&gt;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8221;&#8217; Creates a Condition which combines two other Conditions<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8221;&#8217; <\/span><span lang=\"EN\">&lt;\/summary&gt;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8221;&#8217; <\/span><span lang=\"EN\">&lt;typeparam name=&#8221;T&#8221;&gt;<\/span><span lang=\"EN\">The type the condition will execute against<\/span><span lang=\"EN\">&lt;\/typeparam&gt;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8221;&#8217; <\/span><span lang=\"EN\">&lt;param name=&#8221;cond1&#8243;&gt;<\/span><span lang=\"EN\">The first Condition<\/span><span lang=\"EN\">&lt;\/param&gt;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8221;&#8217; <\/span><span lang=\"EN\">&lt;param name=&#8221;condType&#8221;&gt;<\/span><span lang=\"EN\">The operator to use on the conditions<\/span><span lang=\"EN\">&lt;\/param&gt;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8221;&#8217; <\/span><span lang=\"EN\">&lt;param name=&#8221;cond2&#8243;&gt;<\/span><span lang=\"EN\">The second Condition<\/span><span lang=\"EN\">&lt;\/param&gt;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8221;&#8217; <\/span><span lang=\"EN\">&lt;returns&gt;<\/span><span lang=\"EN\">A new Condition which combines two Conditions into one according to the specified operator<\/span><span lang=\"EN\">&lt;\/returns&gt;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8221;&#8217; <\/span><span lang=\"EN\">&lt;remarks&gt;&lt;\/remarks&gt;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Shared<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\"> Combine(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> cond1 <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T), _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> condType <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Compare, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> cond2 <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>Return<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T).Combine(cond1, condType, cond2)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;Combines multiple conditions according to the specified operator<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Shared<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\"> Combine(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> cond1 <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T), _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> condType <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Compare, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">ParamArray<\/span><span lang=\"EN\"> conditions() <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>Return<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T).Combine(cond1, condType, conditions)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;Combines two Expressions according to the specified operator (condType)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Protected<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Shared<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\"> CombineExpression(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> left <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Expression, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> condType <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Compare, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> right <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Expression) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Expression<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>&#8216;Join the Expressions based on the operator<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Select<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> condType<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<span>&nbsp;&nbsp;&nbsp; <\/span><\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.Or : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Expression.Or(left, right)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.And : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Expression.And(left, right)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.Xor : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Expression.ExclusiveOr(left, right)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.Equal : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Expression.Equal(left, right)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.OrElse : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Expression.OrElse(left, right)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.AndAlso : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Expression.AndAlso(left, right)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.NotEqual : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Expression.NotEqual(left, right)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.LessThan : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Expression.LessThan(left, right)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.GreaterThan : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Expression.GreaterThan(left, right)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.LessThanOrEqual : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Expression.LessThanOrEqual(left, right)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.GreaterThanOrEqual : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Expression.GreaterThanOrEqual(left, right)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.Like<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>&nbsp;&nbsp;&nbsp; <\/span><\/span><span lang=\"EN\">&#8216;For the Like operator we encode a call to the LikeString method in the VB runtime<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Dim<\/span><span lang=\"EN\"> m = <\/span><span lang=\"EN\">GetType<\/span><span lang=\"EN\">(CompilerServices.Operators).GetMethod(<\/span><span lang=\"EN\">&#8220;LikeString&#8221;<\/span><span lang=\"EN\">)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Expression.Call(m, left, right, Expression.Constant(CompareMethod.Binary))<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Else<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">Throw<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">New<\/span><span lang=\"EN\"> ArgumentException(<\/span><span lang=\"EN\">&#8220;Not a valid Condition Type&#8221;<\/span><span lang=\"EN\">, <\/span><span lang=\"EN\">&#8220;condType&#8221;<\/span><span lang=\"EN\">, <\/span><span lang=\"EN\">Nothing<\/span><span lang=\"EN\">)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Select<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;Since both type parameters must be the same, we can turn what would normally<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;be a Func(Of T, T, Boolean) into a Func(Of T, Boolean)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Protected<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Shared<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\"> CombineFunc(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> d1 <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Func(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T, <\/span><span lang=\"EN\">Boolean<\/span><span lang=\"EN\">), _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> condType <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Compare, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> d2 <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Func(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T, <\/span><span lang=\"EN\">Boolean<\/span><span lang=\"EN\">)) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Func(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T, <\/span><span lang=\"EN\">Boolean<\/span><span lang=\"EN\">)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>&#8216;Return a delegate which combines delegates d1 and d2<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Select<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> condType<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<span>&nbsp;&nbsp;&nbsp; <\/span><\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.Or : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\">(x) d1(x) <\/span><span lang=\"EN\">Or<\/span><span lang=\"EN\"> d2(x)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.And : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\">(x) d1(x) <\/span><span lang=\"EN\">And<\/span><span lang=\"EN\"> d2(x)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.Xor : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\">(x) d1(x) <\/span><span lang=\"EN\">Xor<\/span><span lang=\"EN\"> d2(x)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.Equal : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\">(x) d1(x) = d2(x)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.OrElse : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\">(x) d1(x) <\/span><span lang=\"EN\">OrElse<\/span><span lang=\"EN\"> d2(x)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.AndAlso : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\">(x) d1(x) <\/span><span lang=\"EN\">AndAlso<\/span><span lang=\"EN\"> d2(x)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.NotEqual : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\">(x) d1(x) &lt;&gt; d2(x)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.LessThan : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\">(x) d1(x) &lt; d2(x)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.GreaterThan : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\">(x) d1(x) &gt; d2(x)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.LessThanOrEqual : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\">(x) d1(x) &lt;= d2(x)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> Compare.GreaterThanOrEqual : <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\">(x) d1(x) &gt;= d2(x)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Case<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Else<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>&nbsp;&nbsp;&nbsp; <\/span><\/span><span lang=\"EN\">Throw<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">New<\/span><span lang=\"EN\"> ArgumentException(<\/span><span lang=\"EN\">&#8220;Not a valid Condition Type&#8221;<\/span><span lang=\"EN\">, <\/span><span lang=\"EN\">&#8220;condType&#8221;<\/span><span lang=\"EN\">)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Select<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;Guarantees that we get the same instance of a ParameterExpression for a given type t.<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Protected<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Shared<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\"> GetParamInstance(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> dataType <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Type) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> ParameterExpression<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">&#8216;Parameters are matched by reference, not by name, so we cache the instances in a Dictionary.<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">If<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Not<\/span><span lang=\"EN\"> ParamTable.ContainsKey(dataType.Name) <\/span><span lang=\"EN\">Then<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<span>&nbsp;&nbsp;&nbsp; <\/span>ParamTable.Add(dataType.Name, Expression.Parameter(dataType, dataType.Name))<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">If<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>Return<\/span><span lang=\"EN\"> ParamTable.Item(dataType.Name)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Class<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Class<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T) : <\/span><span lang=\"EN\">Inherits<\/span><span lang=\"EN\"> Condition<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;Delegate that contains a compiled expression tree which can be run locally<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Friend<\/span><span lang=\"EN\"> del <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Func(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T, <\/span><span lang=\"EN\">Boolean<\/span><span lang=\"EN\">)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Friend<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Sub<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">New<\/span><span lang=\"EN\">()<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Sub<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Friend<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Sub<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">New<\/span><span lang=\"EN\">(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> propName <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">String<\/span><span lang=\"EN\">, <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> condType <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Compare, <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> value <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Object<\/span><span lang=\"EN\">, <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> valueType <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Type)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>&#8216;Split the string to handle nested property access<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Dim<\/span><span lang=\"EN\"> s = propName.Split(<\/span><span lang=\"EN\">&#8220;.&#8221;c<\/span><span lang=\"EN\">)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">&#8216;Get the PropertyInfo instance for propName<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Dim<\/span><span lang=\"EN\"> pInfo = <\/span><span lang=\"EN\">GetType<\/span><span lang=\"EN\">(T).GetProperty(s(0))<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Dim<\/span><span lang=\"EN\"> paramExpr = GetParamInstance(<\/span><span lang=\"EN\">GetType<\/span><span lang=\"EN\">(T))<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Dim<\/span><span lang=\"EN\"> callExpr = Expression.MakeMemberAccess(paramExpr, pInfo)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">&#8216;For each member specified, construct the additional MemberAccessExpression<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">&#8216;For example, if the user says &#8220;myCustomer.Order.OrderID = 4&#8221; we need an<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">&#8216;additional MemberAccessExpression for &#8220;Order.OrderID = 4&#8221;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">For<\/span><span lang=\"EN\"> i = 1 <\/span><span lang=\"EN\">To<\/span><span lang=\"EN\"> UBound(s)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<span>&nbsp;&nbsp;&nbsp; <\/span>pInfo = pInfo.PropertyType.GetProperty(s(i))<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;callExpr = Expression.MakeMemberAccess(callExpr, pInfo)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Next<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">&#8216;ConstantExpression representing the value on the left side of the operator<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Dim<\/span><span lang=\"EN\"> valueExpr = Expression.Constant(value, valueType)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Dim<\/span><span lang=\"EN\"> b <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Expression = CombineExpression(callExpr, condType, valueExpr)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;LambdaExpr = Expression.Lambda(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> Func(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T, <\/span><span lang=\"EN\">Boolean<\/span><span lang=\"EN\">))(b, <\/span><span lang=\"EN\">New<\/span><span lang=\"EN\"> ParameterExpression() {paramExpr})<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">&#8216;Compile the lambda expression into a delegate<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;del = <\/span><span lang=\"EN\">DirectCast<\/span><span lang=\"EN\">(LambdaExpr.Compile(), Func(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T, <\/span><span lang=\"EN\">Boolean<\/span><span lang=\"EN\">))<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Sub<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;Combines two conditions according to the specified operator<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Friend<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Overloads<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Shared<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\"> Combine(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> cond1 <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T), _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> condType <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Compare, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> cond2 <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>Dim<\/span><span lang=\"EN\"> c <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">New<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Dim<\/span><span lang=\"EN\"> b <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Expression = CombineExpression(cond1.LambdaExpr.Body, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; condType, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cond2.LambdaExpr.Body)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">Dim<\/span><span lang=\"EN\"> paramExpr() = <\/span><span lang=\"EN\">New<\/span><span lang=\"EN\"> ParameterExpression() {GetParamInstance(<\/span><span lang=\"EN\">GetType<\/span><span lang=\"EN\">(T))}<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">&#8216;Create the LambdaExpression and compile the delegate<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;c.LambdaExpr = Expression.Lambda(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> Func(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T, <\/span><span lang=\"EN\">Boolean<\/span><span lang=\"EN\">))(b, paramExpr)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;c.del = Condition.CombineFunc(cond1.del, condType, cond2.del)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> c<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;Combines multiple conditions according to the specified operator<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Friend<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Overloads<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Shared<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\"> Combine(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> cond1 <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T), _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> condType <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Compare, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">ParamArray<\/span><span lang=\"EN\"> conditions() <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>Dim<\/span><span lang=\"EN\"> finalCond = cond1<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">For<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Each<\/span><span lang=\"EN\"> c <\/span><span lang=\"EN\">In<\/span><span lang=\"EN\"> conditions<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<span>&nbsp;&nbsp;&nbsp; <\/span>finalCond = Condition.Combine(finalCond, condType, c)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Next<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> finalCond<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;Run query locally instead of remotely<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\"> Matches(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> row <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> T) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Boolean<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> del(row) <\/span><span lang=\"EN\">&#8216;passes the row into the delegate to see if it&#8217;s a match<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216;Overloaded operators &#8211; allows syntax like &#8220;(condition1 Or condition2) And condition3&#8221;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Shared<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Operator<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">And<\/span><span lang=\"EN\">(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> c1 <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T), <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> c2 <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Condition.Combine(c1, Compare.And, c2)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Operator<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Shared<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Operator<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Or<\/span><span lang=\"EN\">(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> c1 <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T), <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> c2 <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Condition.Combine(c1, Compare.Or, c2)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Operator<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Shared<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Operator<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Xor<\/span><span lang=\"EN\">(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> c1 <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T), <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> c2 <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>Return<\/span><span lang=\"EN\"> Condition.Combine(c1, Compare.Xor, c2)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Operator<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Class<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span><\/span><span lang=\"EN\">&#8216;Represents a condition like &#8220;object.Property = value&#8221;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>&#8216;In this case object is of type T, and value is of type S<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>&#8216;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>&#8216;Even though most of the logic for this is already in the base class, <\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>&#8216;defining a second generic parameter means the user doesn&#8217;t have to<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>&#8216;pass in a System.Type &#8211; it can just be inferred.<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Class<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T, S) : <\/span><span lang=\"EN\">Inherits<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">Friend<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Sub<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">New<\/span><span lang=\"EN\">(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> propName <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">String<\/span><span lang=\"EN\">, <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> condType <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Compare, <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> value <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> S)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">MyBase<\/span><span lang=\"EN\">.New(propName, condType, value, <\/span><span lang=\"EN\">GetType<\/span><span lang=\"EN\">(S))<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Sub<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Class<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">#End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Region<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">#Region<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">&#8220;Extension Methods&#8221;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">&#8216;Filters an IQueryable(Of T) according to the specified condition<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; &lt;Extension()&gt; _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\"> Where(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> source <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> IQueryable(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T), _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> condition <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> IQueryable(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">Dim<\/span><span lang=\"EN\"> callExpr = Expression.Call(<\/span><span lang=\"EN\">GetType<\/span><span lang=\"EN\">(Queryable), <\/span><span lang=\"EN\">&#8220;Where&#8221;<\/span><span lang=\"EN\">, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">New<\/span><span lang=\"EN\"> Type() {source.ElementType}, source.Expression, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expression.Quote(condition.LambdaExpr))<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">CType<\/span><span lang=\"EN\">(source.Provider.CreateQuery(callExpr), IQueryable(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T))<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">&#8216;Filters an IEnumerable(Of T) according to the specified condition<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; &lt;Extension()&gt; _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\"> Where(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> source <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> IEnumerable(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T), _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> condition <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> IEnumerable(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> source.Where(condition.del)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">&#8216;Extension method that can be called off any type that implements IEnumerable(Of T), <\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">&#8216;which constructs a Condition with T as the element type and S as the value&#8217;s type<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; &lt;Extension(), EditorBrowsable(EditorBrowsableState.Always)&gt; _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">Public<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><span lang=\"EN\"> CreateCondition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T, S)(<\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> dataSource <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> IEnumerable(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T), _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> propName <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">String<\/span><span lang=\"EN\">, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> condType <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> condition.Compare, _<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">ByVal<\/span><span lang=\"EN\"> value <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> S) <\/span><span lang=\"EN\">As<\/span><span lang=\"EN\"> Condition(<\/span><span lang=\"EN\">Of<\/span><span lang=\"EN\"> T, S)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">Return<\/span><span lang=\"EN\"> Condition.Create(dataSource, propName, condType, value)<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;&nbsp;&nbsp; <\/span><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Function<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">#End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Region<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <\/span><span lang=\"EN\">Module<\/span><span lang=\"EN\"><\/span><\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">The complete sample (including the code for the ConditionBuilder control) is available in the attached .zip file below.&nbsp; While we\u2019ve got the basics going pretty well, there\u2019s definitely a lot of things you can extend the sample to do, such as:<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">1.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">Add support for Grouping conditions into the ConditionBuilder \u2013 right now you\u2019d have to drop down to the API to construct something like (condition1 Or condition2) And condition3.<\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">2.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\">Add a .Select extension method to dynamically control which fields you bring back from the database.<span>&nbsp; <\/span><span>This will improve performance in situations where you don\u2019t want to return all fields, but you\u2019ll lose strong-typing of your results since the method will have to return IQueryable instead of IQueryable(Of T).<\/span><\/font><\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">3.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font size=\"3\"><font face=\"Calibri\"><span>Add extension methods for OrderBy, Take, Skip, Distinct etc\u2026&nbsp; Each of these methods can still return strongly-typed results since they don\u2019t change the element type; if you pass in T they return T<\/span><span>.<\/span><\/font><\/font><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">4.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\" size=\"3\">The Condition API supports nested property access (i.e. Where customer.Orders.Salesman.Name = \u201cBob\u201d), but it\u2019d take a bit more work to surface this in the ConditionBuilder control.<\/font><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\"><span>That\u2019s everything, now all you have to do is<\/span> download <span><a href=\"http:\/\/msdn2.microsoft.com\/en-us\/vstudio\/aa700831.aspx\"><font color=\"#800080\">Beta2<\/font><\/a><\/span> and try it out!<\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">Jonathan<span><\/span><\/font><\/font><\/p>\n<p><\/span><\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/MSDNBlogsFS\/prod.evol.blogs.msdn.com\/CommunityServer.Components.PostAttachments\/00\/04\/63\/54\/06\/DynamicCondition.zip\">DynamicCondition.zip<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A common requirement in forms-over-data applications is that users be able to search by any combination of fields to construct a dynamic query at run time.&nbsp; For example, the search feature in this application allows the user to find all records that meet criteria defined on multiple columns: &nbsp; &nbsp; &nbsp; LINQ makes it easy [&hellip;]<\/p>\n","protected":false},"author":260,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[192,195],"tags":[77,83,94,117,166],"class_list":["post-5553","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-featured","category-visual-basic","tag-iqueryable","tag-jonathan-aneja","tag-linqvb9","tag-orcas","tag-vb2008"],"acf":[],"blog_post_summary":"<p>A common requirement in forms-over-data applications is that users be able to search by any combination of fields to construct a dynamic query at run time.&nbsp; For example, the search feature in this application allows the user to find all records that meet criteria defined on multiple columns: &nbsp; &nbsp; &nbsp; LINQ makes it easy [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/5553","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/users\/260"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=5553"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/5553\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media\/8818"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media?parent=5553"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=5553"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=5553"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}