LINQ Query to Return multiple results - c#

I am trying to write a textbox that will search on 5 DB columns and will return every result of a given search, ex. "Red" would return: red ball, Red Williams, etc. Any examples or similar things people have tried. My example code for the search.
Thanks.
ItemMasterDataContext db = new ItemMasterDataContext();
string s = txtSearch.Text.Trim();
var q = from p in db.ITMSTs
where p.IMITD1.Contains(s) ||
p.IMITD2.Contains(s) ||
p.IMMFNO.Contains(s) ||
p.IMITNO.Contains(s) ||
p.IMVNNO.Contains(s)
select p;
lv.DataSource = q;
lv.DataBind();

"q" in your example will be an IQueryable<ITMST>. I don't think the Datasource property of WebControl know what to do with that. try writing that line as:
lv.DataSource = q.ToList();

You can do something like this (syntax may be off )
using(var db = new ItemMasterDataContext())
{
var s = txtSearch.Text.Trim();
var result = from p in db.ITMSTs select p;
if( result.Any(p=>p.IMITD1.Contains(s))
lv.DataSource = result.Where(p=>p.IMITD1.Contains(s))
else if ( result.Any(p=>p.IMITD2.Contains(s))
lv.DataSource = result.Where(p=>p.IMITD1.Contains(s))
lv.DataBind();
}
or you might want to use this Link or this Link from MSDN.
Happy Coding!!

What you have is generally what people would do using linq. If you wanted to get more complex and use database wild cards then take a look at the SqlMethods class in System.Data.Linq.
# James Curran
You can assign the DataSource property q and it will work fine. The only different is when the query gets executed.

Related

Implement this "not in" where clause in LINQ

I have a table here where it gets popuplated with ActiveDirectory users every night. This list included generic AD accounts used for a variety of purposes.
Examples of lastnames of generic accounts:
vendor testing
IT support
Dept1 Printer
Visitor1
Visitor2
Guest1
Guest2 and etc
I want to retrieve all records ignoring these records. Something like
select * from table where lastname not like '%visitor%'
and lastname not like "%support%"
and so on I made this query but it does not do substring comparison.
List<String> _ignoreList = new List<String> { "visitor", "test" };
IQueryable<String> _records =
from _adUserDatas in _adUserDataDBDataContext.ADUserDatas
where
_adUserDatas.accountActive.ToLower().Contains("yes")
&& _adUserDatas.staffStudentType.ToLower().Contains("neither")
&& !_ignoreList.Contains(_adUserDatas.lastName)
orderby _adUserDatas.username
select _adUserDatas.username;
Here's the resulting SQL being sent to SQL Server.
{
SELECT[t0].[username]
FROM[dbo].[ADUserData] AS[t0]
WHERE
(LOWER([t0].[accountActive]) LIKE# p0)
AND
(LOWER([t0].[staffStudentType]) LIKE# p1)
AND
(NOT([t0].[lastName] IN(#p2, #p3)))
ORDER BY[t0].[username]
}
in LINQ query above, it did not ignore a record with the lastname "only for testing acct".
Any ideas on how to implement it using LINQ?
I've search the net but nothing came up.
Thanks a lot
That is because your are checking whether ignoreList contains the LastName, try doing it the other way.. i.e Whether LastName conatins anything from the ignoreList..
&& !_ignoreList.Any( il => _adUserDatas.lastName.Contains( il ) )
This way it will check whether "only for testing acct" contains anything from { "visitor", "test" }
Hm.. it could be hard to get to work like predicate with in clausule.. My solution would be other:
var queryable = from _adUserDatas in _adUserDataDBDataContext.ADUserDatas
where
_adUserDatas.accountActive.ToLower().Contains("yes")
&& _adUserDatas.staffStudentType.ToLower().Contains("neither")
orderby _adUserDatas.username
select _adUserDatas.username;
foreach (var ignore in _ignoreList)
{
var localIgnore = ignore;
queryable = queryable.Where(userName => !userName.Contains(localIgnore))
}
var result = queryable.ToList();
The answer from pwas lead me to one that works for my situation. PredicateBuilder which is mentioned in lots of topics here in SOF.com. http://www.albahari.com/nutshell/predicatebuilder.aspx
Here's the final code:
ADUserDataDBDataContext _adUserDataDBDataContext = new ADUserDataDBDataContext();
IQueryable<String> _records = null;
Expression<Func<ADUserData,Boolean>> _whereClause = PredicateBuilder.True<ADUserData>();
_whereClause = _whereClause.And(ADUserData => ADUserData.accountActive.ToLower().Contains("yes"));
foreach (var _item in _ignoreList)
{
_whereClause = _whereClause.And(ADUserData => !ADUserData.lastName.ToLower().Contains(_item));
}
_records = _adUserDataDBDataContext.ADUserDatas
.Where(_whereClause)
.Select(ADUserData => ADUserData.fan);
return _records.ToList();

Returning results using LINQ and multiple 'keywords'?

I'm new to ASP.Net and LINQ. I have a small project I'm working on. It basically consists of a screen with four text boxes, a listview control and a search button with one database table.
Each text box represents a certain field: Author, Title, Publisher, and Price. What I envision is that a user would input text in one, or more, of the fields and hit the search button. The program would then return whatever results could be found that match the user's criteria.
If I were using an SQL statement, I'd just select every record that matches any of the input fields (i.e. SELECT author, title, publisher, price FROM books WHERE...). However, I'm not quite sure how to do this with LINQ.
So, does anyone have a starting point for me? I've seen LINQ examples with one field as a limiter on the search:
public void SimpleSearch()
{
DataClasses1DataContext dc = new DataClasses1DataContext();
var q =
from a in dc.GetTable<Books>()
where a.Title == "1984"
select a;
dataGridView1.DataSource = q;
}
But I can't seem to find any other examples that use more than one limiter on the search. I'm beginning to think it isn't possible. If so, can someone recommend a different way for me to accomplish what I'm trying to do? Basically, I just want to search the table for fields that match the user's input and return the results in a listview. Any help would be greatly appreciate.
You should be able to use || as an OR delimiter:
public void SimpleSearch()
{
DataClasses1DataContext dc = new DataClasses1DataContext();
var q =
from a in dc.GetTable<Books>()
where a.Title == "1984" || a.Author == "Stephen King" || a.Price == 5.99m
select a;
dataGridView1.DataSource = q;
}
You can also use && to do an AND search instead of ||
I like to use contains to make the search a little more fuzzy and also I like to set everything to lowercase so there is no case sensitivity issues when performing the search.
public void SimpleSearch()
{
DataClasses1DataContext dc = new DataClasses1DataContext();
var search = txtSearch.Text.ToLower();
var q =
from a in dc.GetTable<Books>()
where a.Title.ToLower() == search ||
a.Author.ToLower() == search ||
a.Author.ToLower().Contains(search) ||
a.Title.ToLower().Contains(search)
select a;
dataGridView1.DataSource = q;
}

NOT IN for LINQ?

Is there a way for me to filter Employees by group:
ex:
List<String> notInGroups = GetNotInGroups();
var list = from p in employees
where p.Group.Name notin(notInGroups)
select p;
Is there some way to do something like this?
Thanks
You can do !Contains, like:
var list = from p in employees
where !notInGroups.Contains(p.Group.Name)
select p;
Not able to test, but won't something like this work?
var notInGroups = GetNotInGroups();
var list = from p in employees
where notInGroups.Contains(p.Group.Name) == false
select p;
Try where !notInGroups.Contains(p.Group.Name); as your WHERE clause.
List is not particularly well suited for the task of searching through the collection to see if it contains a particular item, which is exactly what you want to do. While writing the code is easy enough (there are already a lot of answers showing how) you will benefit noticeably from using a more appropriate data structure that can be more efficiently searched, such as a HashSet:
var notInGroups = new HashSet<string>(GetNotInGroups());
var list = from p in employees
where !notInGroups.Contains(p.Group.Name)
select p;
You can do something like this..
List<String> notInGroups = GetNotInGroups();
var list = from p in employees
where !(notInGroups.Contains(p.Group.Name))
select p;

How to improve this LINQ query for search

Can I improve this LINQ query
var filter = from Dep in deptlist
where (Dep.DepNm.StartsWith(txt1.Text.ToLower())
|| Dep.DepNm.StartsWith(txt1.Text.ToUpper())
||Dep.DepNm.Contains(txt1.Text))
select Dep;
Currently, you do a .Text, .Text.ToUpper() and .Text.ToLower() of the fixed value per item; (the ToUpper() etc being relatively expensive); you can lift this out:
string text = txt1.Text, upper = text.ToUpper(), lower = text.ToLower();
var filter = from Dep in deptlist
where Dep.DepNm.StartsWith(lower) || Dep.DepNm.StartsWith(upper)
|| Dep.DepNm.Contains(text))
select Dep;
I'm assuming here that .DepNm is trivially cheap. If this is actually an expensive property to query, you can use let to minimise the calls:
var filter = from Dep in deptlist
let name = Dep.DepNm
where name.StartsWith(lower) || name.StartsWith(upper)
|| name.Contains(text))
select Dep;
var filter = from Dep in deptlist
where Dep.where(d => d.DepNm.ToUpper().Conatins(txt1.Text.ToUpper()))
select Dep;
If it's possible in your solution, add lambda expressions. So you saved at least one line :)
EDIT:
Forget what I was saying, this is MUCH shorter:
var filter = deptlist.where(d => d.DepNm.ToUpper().Conatins(txt1.Text.ToUpper())).ToList();
I think it's faster because there is less conditions.
var filter = from Dep in deptlist
where (Dep.DepNm.StartsWith(txt1.Text, StringComparison.OrdinalIgnoreCase))
||Dep.where(d => d.DepNm.ToUpper().Contains(txt1.Text.ToUpper()))
select Dep;
answer is good , i refer viewing this link that relation with search and improvement use query linq in search with empty field
this is multiple choice for filling or not filling textbox, but this answer is work when :
you are one field filling or two field filling or .. 7th field filling .

Linq to SQL: DataTable.Rows[0]["ColumnName"] equivalent

Consider this:
var query = from r in this._db.Recipes
where r.RecipesID == recipeID
select new { r.RecipesID, r.RecipesName };
How would i get individual columns in my query object without using a for-loop?
Basicly: how do I translate DataTable.Rows[0]["ColumnName"] into Linq syntax?
It's really unclear what you are looking for, as your two samples are compatible.
As close as I can figure, what you want is:
var rows = query.ToList();
string name = rows[0].RecipesName;
string name = this._db.Recipes.Single(r => r.RecipesID == recipeID).RecipesName;
This is the way to go about it:
DataContext dc = new DataContext();
var recipe = (from r in dc.Recipes
where r.RecipesID == 1
select r).FirstOrDefault();
if (recipe != null)
{
id = recipe.RecipesID;
name = recipe.RecipesName;
}
Sorry, misunderstood your question. As others are saying, you can use ToList() to get a List back. An alternative if all you need is the first one, just use:
query.First().ColumnName
or if you want to avoid an exception on empty list:
var obj = query.FirstOrDefault();
if (obj != null)
obj.ColumnName;
Original Answer (so the comment makes sense):
Use Linq to Datasets. Basically would be something like:
var query = from r in yourTable.AsEnumerable()
select r.Field<string>("ColumnName");

Categories

Resources