Iterate data in anonymous variable - linq

I have a DataTable containing some data, and I am going to fetch some data from it using Linq to datatable.
The query looks like this:
var requiredData=dt.AsEnumerable()
.Where(row => row.Field<byte>("id") == 1)
.Select(x=> {
id = x.Field<int>("id"),
YYYYY = x.Field<string>("ColumnName2"),
ZZZZZ = x.Field<string>("ColumnName3")
}
);
Now, Please how do I iterate-through "requiredData"?

You could use a foreach loop:
foreach (var item in requiredData)
{
// TODO: use item.id, item.YYYYY and item.ZZZZZ here
}

Related

Trim whitespace from DataTable cells with Linq

This piece of code works to trim all spaces in each datacell of each datarow.
How can I get this code:
var dataRows = dataTable.AsEnumerable();
foreach (var row in dataRows)
{
var cellList = row.ItemArray.ToList();
row.ItemArray = cellList.Select(x => x.ToString().Trim()).ToArray();
}
into one line of code so I don't have to loop through each row? Something like this but it doesn't work:
dataTable.AsEnumerable().Select(y => y.ItemArray.ToList()).Select(x => x.ToString().Trim());
If you love LINQish stype:
dataTable.AsEnumerable().ToList()
.ForEach(row =>
{
var cellList = row.ItemArray.ToList();
row.ItemArray = cellList.Select(x => x.ToString().Trim()).ToArray();
});
With linq you can't change item values finally you should run for loop (or foreach) to change fields value.
for example
var iq = obj from dataTable.asEnumerable() select new{
PersonName = a.Field<string>("PersonName"),
PersonID = a.Field<decimal>("PersonID"),
ParticipantString = a.Field<string>("DisplayString"),
PersonUserName = d.Field<string>("UserName")
}

Linq GroupBy to alter list

I have a list of items in an IList<>.Each listitem has a date and a few other fields.
I need to order the list by date and then change the list to only show a date for the first item and effectively set the date field to null for the other items if the date is repeated.
Example:
12/01/2012 500
12/01/2012 700
15/02/2012 900
15/02/2012 1100
27/05/2012 2000
Desired Result:
12/01/2012 500
null 700
15/02/2012 900
null 1100
27/05/2012 2000
Is this possible with the linq group by and order by?
Thanks
LINQ operators are not supposed to change the underlying data. You'd better use regular foreach if you're going to modify the data.
This should probably work:
var groups = items.GroupBy(x => x.Date).ToArray();
foreach (var group in groups)
{
foreach (var item in group.Skip(1)) item.Date = null;
}
I would avoid using such a construction since you'll have to double-check that GroupBy preserves order. Instead I would use something like this:
var sortedItems = items.OrderBy(x => x.Date);
var lastVisitedDate = (DateTime?) null;
foreach (var item in sortedItems)
if (Equals(item.Date, lastVisitedDate)) item.Date = null;
else lastVisitedDate = item.Date;
This should work:
var list = new List<DateItem>();
// Initialization ...
var dups = list.Select((Item,Index) => new{ Item,Index })
.GroupBy(x => x.Item.Date)
.Where(g => g.Count() > 1);
foreach(var dup in dups)
{
foreach (var nullable in dup.OrderBy(x => x.Item.Date).Skip(1))
{
list[nullable.Index].Date = null;
}
}
Assuming your class looks similar to this:
class DateItem {
public DateTime? Date;
public int OtherField;
}
Edit: Here's a working demo: http://ideone.com/cVL4G
One way is to use LINQ to get all of the followers and then set their dates to null in a loop:
// Use ToList() to make sortedItems non-lazy so it won't get ordered each time it's called.
var sortedItems = items.OrderBy(x => x.Date).ToList();
var followers = sortedItems.GroupBy(item => item.Date)
.SelectMany(group => group.Skip(1));
foreach (var follower in followers)
{
follower.Date = null;
}
// Now you can use sortedItems.
Or if you prefer the query syntax:
var followers = from item in sortedItems
group item by item.Date into grp
from follower in grp.Skip(1)
select follower;

how to select collection type navigation property's value

I have 3 tables, team(id,name) player(id,teamid,name) playerdetail(id,playerid,height,weight), the relationship between team and player is one to many, the relationship between player and playerdetail is one to one.
I want to use eager loading to load all the information and print out the name of players who is higher than 2 meters.
I have write the code below,
using (var context = new TestEntities())
{
var query = from t in context.Teams.Include("Players.PlayerDetails") select t;
foreach (var v in query)
{
Console.WriteLine(v.Players.Any(x => x.PlayerDetails.Any(y => y.Height > 200)));
}
Console.Read();
}
It prints out only true and false, how can I modify it and make it print out the name of player?
Thanks in advance
Why don't you just query the players through context.Players like below?
using (var context = new TestEntities())
{
var query = context.Players.Include("Team").Include("PlayerDetails")
.Where(p => p.Height > 200);
foreach (var v in query)
{
Console.WriteLine(v.Name);
}
Console.Read();
}

linq select from database where ID in an ArrayList

I have an array-list that contains some UserID.
I need a query like this:
vat tmp= users.select(a=> a.UserID in (arraylist));
what can I do?
If it's actually in an ArrayList, you should create a List<T> or array first. Then you can use Contains:
// Use the appropriate type, of course.
var ids = arraylist.Cast<string>().ToList();
var tmp = users.Select(a => ids.Contains(a.UserID));
While using Contains on the plain ArrayList may well compile, I would expect it to fail at execution time, assuming users is an IQueryable<>.
List<long> list =new List<long>();
var selected = from n in users where list.Contains(n.ID) select n ;
OR
var selected = users.Where(a=> list.Contains(a.ID)).ToList();
This is the solution I used.
public static IEnumerable<SettingModel> GetSettingBySettingKeys(params string[] settingKey)
{
using (var db = new BoxCoreModelEntities())
{
foreach (var key in settingKey)
{
var key1 = key;
yield return Map(db.Settings.Where(s => s.SettingKey == key1).First());
}
}
}

Linq to CSV select by column

If I have the following (sample) text file;
year,2008,2009,2010
income,1000,1500,2000
dividends,100,200,300
net profit,1100,1700,2300
expenses,500,600,500
profit,600,1100,1800
Is there a way in Linq that I can select the expenses for 2010 only?
So far I have the following which gets me all the data;
var data = File.ReadAllLines(fileName)
.Select(
l => {
var split = l.CsvSplit();
return split;
}
);
foreach (var item in data)
Console.WriteLine("{0}: ${1}", item[0], item[1]);
If you know it's always the 3rd value column, then
// the expenses row
var query = data.Single(d => d[0] == "expenses");
// the third column
return query[3];
and if you don't, then
var columnNumber = Array.IndexOf(data.First(), "2010");
return query[columnNumber];
See LINQtoCSV, its a library that does all this for you. I've used it, and it works like a charm.
http://www.codeproject.com/KB/linq/LINQtoCSV.aspx

Resources