SearchExtensions: Search strings with the new Fluent API
I am pleased to announce a NEW
Fluent Search API for SearchExtensions nuget package
As of version 0.5, SearchExtensions now has a fluent API enabling a more control over your queries as well as making them easy to read. Here are the changes:
IQueryable Searching
Because of the Fluent API update, we are now able to offer up some additional methods to search.
Methods
Search methods available to IQueryable data are:
Containing
- target property contains search term(s)IsEqual
- target property equals search term(s)StartsWith
- target property starts with search term(s)
###Setup
Previous functionality of searching against any number of properties is still supported. Now however you only define the properties you want to perform a search against as part of the setup action.
using NinjaNye.SearchExtensions.Fluent;
//...
var result = data.Search(x => x.Name, x => x.Description)
Defining more than one property states that you want results that are matched within any of the properties.
Once we have identified the properties we wish to search we can start to perform some search actions
Performing a Containing
search
Return all records where the Name property contains "search"
var result = data.Search(x => x.Name).Containing("search");
Return all records where the Name property OR the Description property contains "search":
var result = data.Search(x => x.Name, x => x.Description).Containing("search");
Return all records where the Name property OR the Description property contains "search" OR "term":
var result = data.Search(x => x.Name, x => x.Description).Containing("search", "term");
Performing a IsEqual
search
Return all records where the Name property equals "search"
var result = data.Search(x => x.Name).IsEqual("search");
Return all records where the Name property OR the Description property equals "search":
var result = data.Search(x => x.Name, x => x.Description).IsEqual("search");
Return all records where the Name property OR the Description property equals "search" OR "term":
var result = data.Search(x => x.Name, x => x.Description).IsEqual("search", "term");
Performing a StartsWith
search
Return all records where the Name property starts with "search"
var result = data.Search(x => x.Name).StartsWith("search");
Return all records where the Name property OR the Description property starts with "search":
var result = data.Search(x => x.Name, x => x.Description).StartsWith("search");
Return all records where the Name property OR the Description property starts with "search" OR "term":
var result = data.Search(x => x.Name, x => x.Description).StartsWith("search", "term");
###Combining instructions
With the latest version of SearchExtensions
you can also combine search actions. For instance
Search where a Name property starts with
"john AND is containing
"nye":
var result = queryableData.Search(x => x.Name)
.StartsWith("john")
.Containing("nye");
The ability to pass multiple search terms to any of the action methods still remains. The following returns any record where the Name
property OR the Title
property starts with either "john" or "web" AND contains "nye" or "developer"
var result = queryableData.Search(x => x.Name, x.Title)
// that starts with "john" OR "web"
.StartsWith("john", "web")
// and contains ins "nye" OR "developer"
.Containing("nye", "developer")
##IEnumerable (in memory) Searches
The fluent API has also been extended to support IEnumerable
collections (not just IQueryable
).
This means you can now perform all of the above searches on in memory collections should you need to. The important thing to remember when performing an in memory search is to set the culture to the type of string comparison you wish to perform. If SetCulture
is not specified, StringComparison.CurrentCulture
is used.
###How to: Performing IEnumerable searches
These methods are identical to that of the IQueryable
methods except the comparison functions have an additional overload that takes a string comparison.
IEnumerable extensions also has an additional method named EndsWith
.
var result = enumerableData.Search(x => x.Description)
// Set culture for comparison
.SetCulture(StringComparison.OrdinalIgnoreCase)
.StartsWith("abc")
.EndsWith("xyz")
.Containing("mno");
It is also possible to set the comparison multiple times
var result = enumerableData.Search(x => x.Description)
.SetCulture(StringComparison.OrdinalIgnoreCase)
.StartsWith("abc") // Uses OrdinalIgnoreCase
.SetCulture(StringComparison.Ordinal)
.EndsWith("xyz") // Uses Ordinal
.SetCulture(StringComparison.CurrentCulture)
.Containing("mno"); //Uses CurrentCulture
I hope you all enjoy this latest release. This package is still under development so I welcome any feedback you have.
Installation
To install SearchExtensions you can simply write the following in you Package Manager Console
<p class="nuget-badge"><code>PM> Install-Package NinjaNye.SearchExtensions</code></p>I see that its possible to search something starting with "x" and containing "X".. but... Is it possible to do a search by equal OR containing ?? For example equals "X" or containing "Y".
Hi Gas,
The feature is not directly supported but you could do something like the following to achieve what you are after:
var equalsX = context.Search(x => x.SrtringOne).EqualTo("X");
var containsY = context.Search(x => x.StringOne).Containing("Y");
The above effectively performs 2 searches, the for records equal to "X" and the second for records containing "Y".
This is not the first time a request like this has come in so maybe I could introduce something like the following that turns and AND operator into and OR operator:
var result = context.Search(x => x.StringOne)
.EqualTo("X")
.Or().Containing("Y");
The Or
prefix could effectively turn any of the filter methods into an OR statement.
Thanks for getting in touch
I was using predicate builder and was doing searches on joined data.
Example..
var predicateF = PredicateBuilder.New<PurchaseOrder>()
.Or(f => f.Vendor.Name.Contains(parms.searchText))
.Or(f => f.LineItems.Any(y => y.StrainName.Contains(parms.searchText)))
.Or(f => f.LineItems.Any(y => y.ToComplianceId.Contains(parms.searchText)))
.Or(f => f.LineItems.Any(y => y.ComplianceId.Contains(parms.searchText)))
.Or(f => f.Manifest.ComplianceId.Contains(parms.searchText))
Is this possible?
Hi John, thanks for this excellent nuget package. I wanted to check if there is a possibility to search two string and uniquely find a record. What I mean is that for instance if I have a row in my table with name 'fawaz' and postcode 'sw17' I want to only bring this row and not the others where others where the name of postcode matches. Is that possible with the current version? How does it perform on a table record of around 200,000 records?
Cheers Fawaz
Hi Fawaz,
If you want to achieve an AND
search, you can do something like the following:
var result = queryableData.Search(x => x.Name).EqualTo("fawaz")
.Search(x => x.Postcode).EqualTo("sw17");
This will perform a search and return all records that have both these values set
Hope this helps