order keyvaluepair using linq - c#

I have the following list keyvaluepair
var countryList = new List<KeyValuePair<string,int>>();
which I then populate with a while loop from the db something like this
countryList.Add(new KeyValuePair<string, int>("cname",1));
I then want to query it using linq and order it at the same time, I have this
var lst = from s in countryList
orderby s.[0]
select s;
As you can guess it doesn't work, I know why it's the s.[0] but can someone tell me what the correct syntax is?
thanks

I would make it in a one line instead
var sortedCountryList = countryList.OrderBy(s=>s.Key);
and if you only want the country names in a list
var sortedCountryList = countryList.OrderBy(s=>s.Key).Select(s=>s.Value);

var lst = from s in countryList
orderby s.Key
select s;

Related

How to match a list of item to database in C#

I have a list of string
List<string> list = new List<string>();
list.Add("john");
list.Add("David");
list.Add("Sam");
Now I want to check whether my column in database contains these list Items.
var v = db.employee.where(s => s.Content.Contains(list));
My question is how can I match all list items to database column in just one query without using any loop. The query must return result if single list item is matched with column. The query I mentioned above not working. Please help me to solve this.
This will only work with the assumption that your db is an Entity Framework DbContext and that s.Content is a string. If you're using some other ORM then it may not work.
List<string> list = new List<string>();
list.Add("john");
list.Add("David");
list.Add("Sam");
var v = db.employee.Where(s => list.Contains(s.Content)).ToList();
You can do this:
List<string> list = new List<string>();
list.Add("john");
list.Add("David");
list.Add("Sam");
var v = db.employee
.ToList()
// This filtering doesn't happen in your SQL server.
.Where(s => list.Any(x => s.Content.Contains(x)));
You can try to omit .ToList() line but I'm afraid your ORM will not know how to convert the query to SQL.
If you want the whole query to be executed in SQL you should consider building the query this way:
var query = db.employee.AsQueryable();
query = list.Aggregate(query,
(query, name) => query.Where(empl => empl.Content.Contains(name)));
what about:
List<string> list = new List<string> {"john", "Warwick", "Sam"};
var vresult = _db.employee.Where(x => list.Contains(x.Content)).ToList();
please indicate what you are expecting...? like how is it not working?
If return is different than null, exists.
public List<Employee> CheckIfExists(List<string> nameList)
{
if (nameList == null)
{
return null;
}
string inClause = "";
foreach (var item in nameList)
{
inClause = string.Format("{0},{1}", inClause, item);
}
return db.employee.SqlQuery("SELECT * FROM employee WHERE employee.Name IN (#p0)", inClause).ToList();
}
Each element of list will be passed as an argument to s.Content.Contains
and here s is an employee record.
var v = db.employee.Where(s => list.Any(s.Content.Contains));
This might help you,
list with name= {"john", "David", "Sam"}
you want to check if John/David/Sam exists in the employee table.
The below query is to check if the particular name exists in employee or not
var _data = _db.employee.Where(emp => list.Any(li => li.name == emp.name)).ToList();
LINQ in query syntax:
var result = from o in db.employee
where list.Contains(o.Content)
select o;

Using datatable in place of list in linq

I wrote the following query in LINQ:
memberlist is List of membershipuserwrapper
List<usercodes> testlist = new List<usercodes>();
testlist.Add(new usercodes { usercode = "na02\\srosner" });
testlist.Add(new usercodes { usercode = "Schie#testtest.com" });
var filtered = (from c in memberList
where (from t in testlist
select t.usercode.ToLower())
.Contains(c.UserName.ToLower())
select c)
.ToList();
Now, I have DataTable with a list of users in place of testlist and I want to use that DataTable in place of my LINQ query.
Can I use that how to do that in way of DataTable?
You should be able to use:
from t in testlist.AsEnumerable()
select t.Field<string>("usercode").ToLower()
in place of the original:
from t in testlist
select t.usercode.ToLower()
Personally, though, I'd say that the List<usercodes> is a vast improvement from a DataTable, and would encourage you to pursue the original version (maybe changing the class-name to UserCodes or similar).

Entity Framework - Join to a List

I need to retrieve a list of entities from my database that matches a list of items in a plain list (not EF). Is this possible with Entity Framework 4.1?
Example:
var list = new List<string> { "abc", "def", "ghi" };
var items = from i in context.Items
where list.Contains(i.Name)
select i;
This works great to return rows that match one property, but I actually have a more complex property:
var list = new List<Tuple<string, string>>
{
new Tuple<string,string>("abc", "123"),
new Tuple<string,string>("def", "456")
};
// i need to write a query something like this:
var items = from i in context.Items
where list.Contains(new Tuple<string,string>(i.Name, i.Type))
select i;
I know that is not valid because it will say it needs to be a primitive type, but is there any way to do what I'm trying to accomplish or will I need to resort to a stored procedure?
You have a few options:
1) You could, of course, write a stored procedure to do what you need and call it.
2) You could read the table into memory and then query the in memory list...that way you don't have to use primitives:
var items = from i in context.Items.ToList()
where list.Contains(new Tuple<string, string>(i.Name, i.Type))
select i;
3) You could also convert your query to use primitives to achieve the same goal:
var items = from i in context.Items
join l in list
on new { i.Name, i.Type } equals
new { Name = l.Item1, Type = l.Item2 }
select i;
I would go with the second option as long as the table isn't extremely large. Otherwise, go with the first.
You need to break it down to sub-properties. For example, something like (this might not compile, i'm not able to test at the moment, but it should give you something to work with):
var items = from i in context.Items
where list.Select(x => x.Item1).Contains(i.Name)
&& list.Select(x => x.Item2).Contains(i.Type)
select i;
You have to think about what the resulting SQL would look like, this would be difficult to do directly in SQL.
My suggestion would be you split out one field of the tuples and use this to cut down the results list, get back the query result then filter again to match one of the tuples e.g.
var list = new List<string> { "abc", "def" };
var list2 = new List<Tuple<string, string>>
{
new Tuple<string,string>("abc", "123"),
new Tuple<string,string>("def", "456")
};
var items = (from i in context.Items
where list.Contains(i.Name)
select i)
.AsEnumerable()
.Where(i => list2.Any(j => j.val1 == i.Name && j.val2 == i.Type);

problem using foreach in linq query result

I have linq query as follows:
var result = (from Customer cust in db select new { userNameList = cust.UserName }).ToList();
i want to loop through each value in the list<>
I tried to use the foreach to accomplish this. It is stupid i could not figure it out
I'm using something like this
foreach (List<string> item in result)
{
if (item.ToString() == userName)
{
userExistsFlag = 1;
}
}
But the .net compiler is just freaking out:
and giving me these errors
Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List'
Cannot convert type 'AnonymousType#1' to 'System.Collections.Generic.List'
Thanks in anticipation
OF ALL THESE IMPLEMENTATIONS WHICH ONE IS MOST EFFICIENT AND CONSUMES LESS RESOURCES.
IT WOULD BE KIND ENOUGH IF SOME ONE CAN CLARIFY THIS FOR ME.
Shorter using Linq:
bool userExistsFlag = result.Any( x=> x.userNameList == userName);
As suggested in the other answers you do not need to project to an anonymous type:
var userNames = (from Customer cust in db select cust.UserName).ToList();
bool userExists = userNames.Contains(userName);
Edit:
The most efficient - if you do not need the set of user names otherwise - is to query the DB directly to check whether the user name exists, so
bool userExists = db.Any( x => x.UserName == userName);
Credit goes to #Chris Shaffer in the comments and #Cybernatet's answer - he was almost there. I would suggest you accept his answer but use Any() ;-)
Try:
var result = (from Customer cust in db select new { userNameList = cust.UserName }).ToList();
userExistsFlag = result.Where(a=> a.userNameList == userName).Count() > 0;
or
userExistsFlag = (
from Customer cust in db
where cust.UserName = userName
select cust
).Count() > 0;
If your query returns a list of names, your FOREACH loop should look like this
foreach( String name in results ){
...
}
Skip using new { userNameList = cust.UserName } which is making it an anonymous instance. You can try
var result = (from Customer cust in db select cust.UserName ).ToList();
if you're just getting the one property and want a list of strings there is no reason to use an anonymous type. code should work like this:
var result = (from Customer cust in db select cust.UserName).ToList();

Question About Querying Linq Results

When you query existing linq results, it's like they're stuck a layer deeper than the original result. Let me explain what I mean by this.
In the example below, after getting ResultSorted, to get to the data therein, you have to use RowSorted.All.TableData.Field, but in the unsorted Result, you could just do Row.TableData.Field. In the sorted data, you have to use .All to get to the rest of the data, which is like an extra layer to get to the data you're looking for.
How can I get it so I can query Result without getting this extra layer? Thanks Stack-O!
var Result =
from a in Db.Table
select new {TableData = a};
var ResultSorted =
from a in Result
orderby a.TableData.Field
select new {All = a};
foreach(var RowSorted in ResultSorted)
{
MessageBox.Show(RowSorted.All.TableData.ToString());
}
You can use
var Result =
from a in Db.Table
select a;
var ResultSorted =
from a in Result
orderby a.Field
select a;
foreach(var RowSorted in ResultSorted)
{
MessageBox.Show(RowSorted.ToString());
}
Edit:
The thing is that
select new {TableData = a};
creates a new anonymous type with a field called TableData, like this
class Tmp1
{
TableType TableData {get; set;}
}
and
select new {All = a};
creates a new anonymous type with a field called TableData, like this
class Tmp2
{
Tmp1 All {get; set;}
}
Edit 2:
If you select a directly you don't create the extra anonymous type, instead you return the TableType.
You are returning a new instance of an anonymous type in each of your LINQ queries:
select new {TableData = a};
select new {All = a};
What you are saying to the compiler is (in the first LINQ query), "Give me a new instance of an anoymous type. I want this anonymous type to have one property named TableData and I want the value for that property to be a."
If you simply return a instead of an anoymous type, you shouldn't need to go through the properties of the nested types to get the data. Try this:
var Result =
from a in Db.Table
select a;
var ResultSorted =
from a in Result
orderby a.TableData.Field
select a;
foreach(var RowSorted in ResultSorted)
{
MessageBox.Show(RowSorted.ToString());
}
var ResultSorted =
from a in Db.Table
orderby a.Field
select a.ToString();
Edit: Fixed, didn't see the first query. This should be identical now. There is no need to create anonymous objects all the time.

Categories

Resources