LINQ - How to do partial searches on multiple criteria using NHibernate.LINQ - linq

I have a search page where a user can enter multiple cities seperated by a comma and we need to get all the real estate properties where the city is one that is entered in the search criteria. For instance the user will enter something like this
cities = Dallas, Austin
The query I have works fine if the user enters a full city name
var cityList = new List{"Dallas", "Austin"};
var properties = Reporsitory.AsQueryable
.Where(x=> cityList.Contains(x.City))
.ToList();
However if I just enter Dal, Aus it does not work. How can I make these partial searches work. Is Dynamic LINQ the only answer? Thanks!

try this
var cityList = new List{"Dallas", "Austin"};
var properties = Reporsitory.AsQueryable
.Where(x=> cityList.Contains(y => x.City.Contains(y)).ToList();
try to search inside the string, i hope it works

I don't know specifically for nHibernate, but Linq to SQL does support this:
.Where(x=> x.StartsWith("Dal"))

var properties = Reporsitory.AsQueryable().Where(x => cityList.Count(c => x.StartsWith(c)) != 0);
Or replace StartWith to Contains...

Related

Dynamic Linq on DataTable error: no Field or Property in DataRow, c#

I have some errors using Linq on DataTable and I couldn't figure it out how to solve it. I have to admit that i am pretty new to Linq and I searched the forum and Internet and couldn't figure it out. hope you can help.
I have a DataTable called campaign with three columns: ID (int), Product (string), Channel (string). The DataTable is already filled with data. I am trying to select a subset of the campaign records which satisfied the conditions selected by the end user. For example, the user want to list only if the Product is either 'EWH' or 'HEC'. The selection criteria is dynaically determined by the end user.
I have the following C# code:
private void btnClick()
{
IEnumerable<DataRow> query =
from zz in campaign.AsEnumerable()
orderby zz.Field<string>("ID")
select zz;
string whereClause = "zz.Field<string>(\"Product\") in ('EWH','HEC')";
query = query.Where(whereClause);
DataTable sublist = query.CopyToDataTable<DataRow>();
}
But it gives me an error on line: query = query.Where(whereClause), saying
No property or field 'zz' exists in type 'DataRow'".
If I changed to:
string whereClause = "Product in ('EWH','HEC')"; it will say:
No property or field 'Product' exists in type 'DataRow'
Can anyone help me on how to solve this problem? I feel it could be a pretty simple syntax change, but I just don't know at this time.
First, this line has an error
orderby zz.Field<string>("ID")
because as you said, your ID column is of type int.
Second, you need to learn LINQ query syntax. Forget about strings, the same way you used from, orderby, select in the query, you can also use where and many other operators. Also you'll need to learn the equivalent LINQ constructs for SQL-ish things, like for instance IN (...) is mapped to Enumerable.Contains etc.
With all that being said, here is your query
var productFilter = new[] { "EWH", "HEC" };
var query =
from zz in campaign.AsEnumerable()
where productFilter.Contains(zz.Field<string>("Product"))
orderby zz.Field<int>("ID")
select zz;
Update As per your comment, if you want to make this dynamic, then you need to switch to lambda syntax. Multiple and criteria can be composed by chaining multiple Where clauses like this
List<string> productFilter = ...; // coming from outside
List<string> channelFilter = ...; // coming from outside
var query = campaign.AsEnumerable();
// Apply filters if needed
if (productFilter != null && productFilter.Count > 0)
query = query.Where(zz => productFilter.Contains(zz.Field<string>("Product")));
if (channelFilter != null && channelFilter.Count > 0)
query = query.Where(zz => channelFilter.Contains(zz.Field<string>("Channel")));
// Once finished with filtering, do the ordering
query = query.OrderBy(zz => zz.Field<int>("ID"));

searching by special character on linq

I need a searching process on linq like this. For example, I will make searching on Name column,and user enters "Ca?an" word to textbox. Question mark will e used for sprecial search character for this sitution.
It will search by Name column and, find Canan,Calan,Cazan etc.
I hope I can explain my problem correctly.
Can anyone give me an idea about this linq query. Thank in advance...
You can use this regular expression (if you are using C#) to check for the "Ca?an".
string d = "DDDDDDDDDDCasanDDDDDDDDDD";
Regex r = new Regex(#"Ca([a-zA-Z]{1})an");
string t = r.Match(d).Value;
Output will be:
"Casan"
You have all your colum stored in a database, then do something like:
List<Person> list = new List<Person>(); //Filled
var res = list.Select(x => r.Match(x.Name));
Output will be a IEnumerable with all the "Persons" who contains in the Name "Ca?an", being ? no matter which letter
You need to convert your search-syntax into an existing search-engine - I'd suggest Regex. So the steps will be:
Safely convert the entered search-string into Regex-pattern
Perform the search in Linq on name-property
Solution:
1: Safely convert search string by replacing '?' with Regex-version of wildchar:
var userInput = "Ca?an";
var regexPattern = Regex.Escape(userInput).Replace(#"\?", ".");
2: Perform search in Linq (assuming itemList implements IEnumerable):
var results = itemList.Where(item => Regex.IsMatch(item.Name, regexPattern));
Hope this helps!

How to search with dynamic entity names with linq

Basically all I'm looking to do is something like the following:
string EntityFrameworkType = "Product";
string searchField = "ProductName";
string searchValue = "My Product";
using( var context = new entitycontext())
{
var result = (from x in context.EntityFrameworkType.Where(l=>l.searchField == searchValue) select x).FirstOrDefault();
}
of course this syntax won't work because context does not contain an entity called "EntityFrameworkType"...
Is it possible to do this another way??? What I'm looking to do in generalize my database duplicate check. In this example, I'm searching for any Product with the Name "My Product". But I'd like to be able to pass in these string for say, ProductCategory with ProductCategoryId = 1.... etc...
you can have a look here to get the idea of how it is done.
You'll need to learn about Expression

how to use a dynamic variable in orderby clause

am a newbie in linq.. am stuck with one scenario. ie,
i have to sort the search results based on user input.
user inputs are Last Name, First Name and Title. for input 3 drop downs are there and i have to sort result based on the values selected.
i tried
order = Request["orders"].Split(',');
var param = order[0];
var p1 = typeof(Test).GetProperty(param);
param = order[1];
var p2 = typeof(Test).GetProperty(param);
param = order[2];
var p3 = typeof(Test).GetProperty(param);
model.Test = (from tests in model.Test
select tests).
OrderBy(x => p1.GetValue(x, null)).
ThenBy(x => p2.GetValue(x, null)).
ThenBy(x => p3.GetValue(x, null));
but it doesn't works.
i want qry like this
from tests in model.Test
select tests).OrderBy(x => x.lastname).
ThenBy(x => x.firstname).ThenBy(x => x.Title);
order[0]== lastname but how can i use it in the place of OrderBy(x => x.order[0])..?
Thanks in advance.
i solved my case as follows
// list of columns to be used for sorting
List<string>order = Request["orders"].Split(',').ToList();
//map the column string to property
var mapp = new Dictionary<string, Func<Test, string>>
{
{"FirstName", x => x.FirstName},
{"LastName", x => x.LastName},
{"SimpleTitle", x => x.SimpleTitle}
};
//user inputted order
var paras = new List<Func<Test, string>>();
foreach (var para in order)
{
if(!string.IsNullOrEmpty(para))
paras.Add(mapp[para]);
}
//sorting
model.Test= model.Test.OrderBy(paras[0]).ThenBy(paras[1]).ThenBy(paras[2]);
Thanks all,
Actually you are looking for dynamic linq query than you can try out Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)
which allow to do like this
it means you can dynamically pass string propertyname to short you collection in orderby function
You can also read about : Dynamic query with Linq
You can compose the expression (any Expression) manually from pieces and then append it to the previous part of query. You can find more info, with example in "Sorting in IQueryable using string as column name".

How do dynamically set group by properties and aggregates in a LINQ query?

I assume I need to use the method call syntax instead of the query expression form, and I know the basics of grouping in the latter. Maybe some gurus can give caveats and advice on using group fields and aggregates obtained at runtime from a configuration, for use in a reporting like structure.
Have you looked at Dynamic Linq? It should do what you want. Have a look at this post from scottgu's blog.
If your data is in xml, linq to xml would allow you to write queries against it in which the certain inputs are strings.
For example:
System.Xml.Linq.XElement myData = GetData();
System.Xml.Linq.XElement result = new XElement("Result",
myData.Elements("Customer")
.GroupBy(e => e.Attributes("Name"))
.Select(g => new XElement("CustomerResult",
new XAttribute("Name" = g.Key,
new XAttribute("Count" = g.Count(),
new XAttribute("MinDate" = g.Min(e => e.Date)
)
);

Resources