I have var item which I want to convert in to a Datatable.
How can I do this.
var items = (from myObj in this.Context.Orders
group myObj by myObj.OrderDate.ToString("yyyy-mm")
into ymGroup
select new { Date = ymGroup.Key, Start = ymGroup.Min(c => c.OrderId), End = ymGroup.Max(c => c.OrderId) });
I need to convert the items into a DataTable. I don't want to use any foreach loop.
How can I do this.?
have a look on:http://www.c-sharpcorner.com/UploadFile/VIMAL.LAKHERA/LINQResultsetToDatatable06242008042629AM/LINQResultsetToDatatable.aspx
Related
I've looked at several answers to similar questions, but none of them solve my problem. All I need to do is get distinct values from a LINQ query (that queries a XML file) and put them into a list. Here is what I have tried:
var XmlData = XDocument.Load("PathToFile");
List<string> XmlItems = new List<string>();
var XQuery = from m in XmlData.Root.Elements()
where m.Attribute("Category").Value.ToString().Equals("TheCategory")
select (m.Attribute("TheAttribute").Value).Distinct().ToString();
XmlItems.AddRange(XQuery);
foreach (var item in XmlItems)
{
ComboBoxTeams.Items.Add(item);
}
The Distinct() function call is not giving the expected result. I'm unfamiliar with how to get distinct values from a LINQ query. Any suggestions?
At this point, your Distinct
var XQuery = from m in XmlData.Root.Elements()
where m.Attribute("Category").Value.ToString().Equals("TheCategory")
select (m.Attribute("TheAttribute").Value).Distinct().ToString();
is only for (m.Attribute("TheAttribute").Value), not for the whole statement
You may need to change it to
var XQuery = from m in XmlData.Root.Elements()
where m.Attribute("Category").Value.ToString().Equals("TheCategory")
select (m.Attribute("TheAttribute").Value.ToString()); //get everything first, ToString probably needed
var XQueryDistinct = XQuery.Distinct(); //get distinct among everything you got
You have the .ToString() and .Distinct() in the wrong places.
var XmlData = XDocument.Load("PathToFile");
List<string> XmlItems = new List<string>();
var XQuery = from m in XmlData.Root.Elements()
where m.Attribute("Category").Value.ToString().Equals("TheCategory")
select (m.Attribute("TheAttribute").Value).Distinct().ToString();
XmlItems.AddRange(XQuery);
foreach (var item in XmlItems)
{
ComboBoxTeams.Items.Add(item);
}
becomes:
var XmlData = XDocument.Load("PathToFile");
var XmlItems = (from m in XmlData.Root.Elements()
where m.Attribute("Category").Value.ToString().Equals("TheCategory")
select (m.Attribute("TheAttribute").Value.ToString())).Distinct();
foreach (var item in XmlItems)
{
ComboBoxTeams.Items.Add(item);
}
If you have a list of simple values, you need to remove the use of Distinct in your select and put after.
var XQuery = (from m in XmlData.Root.Elements()
where m.Attribute("Category").Value.ToString().Equals("TheCategory")
select (m.Attribute("TheAttribute").Value.ToString())).Distinct();
If you have complex objects you have two alternatives:
Using morelinq you can use DistinctBy:
XmlItems.DistinctBy(x => x.WhateverProperty);
Otherwise, you can use a group:
XmlItems.GroupBy(x => x.idOrWhateverOtherProperty)
.Select(g => g.First());
You might try
var uniqueList = yourList.Distinct().ToList();
after you got your non-unique list.
I have an
IEnumerable<typeA> result;
from this result I need to get sum group by some id.
So I have the query
var groupeddata = from data in result
group data by data.Title
into grouped
select new { intid= grouped.Key,
expsum= grouped.Sum(x=>x.expnum)};
now this expsum I need to assign to the items of result where typeA.id is same as intid. Now how to do this assignment?
The simplest approach would probably be to use a dictionary:
var sumDictionary = query.ToDictionary(pair => pair.intid, pair => pair.expsum);
foreach (var item in result)
{
// We don't know which property you actually want to assign to
item.Sum = sumDictionary[item.id];
}
I am using LINQ query to filter data from a datatable and placing the data in to another datatable. For this I am using foreach statement to copy values from var to datatable. The datatable will be containing a very huge no. of rows so can you suggest me a way in which I can do the copying in a single go?
var drdatedisp = from row in dtfullreport.AsEnumerable()
group row by row.Field<string>("Order_Date") into g
select new
{
Order_Date = g.Key,
totalQnty = g.Sum(a => a.Field<int>("Item_Quantity")),
totalTax = g.Sum(a => float.Parse(a.Field<decimal>("TAXAMT").ToString())),
totalAmt = g.Sum(a => float.Parse(a.Field<decimal>("VALAMT").ToString()))
};
DataTable dtdatedisp = new DataTable();
dtdatedisp.Columns.Add("Order_Date");
dtdatedisp.Columns.Add("Item_Quantity");
dtdatedisp.Columns.Add("TAXAMT");
dtdatedisp.Columns.Add("VALAMT");
dtdatedisp.Rows.Clear();
foreach (var g in drdatedisp)
{
DataRow newRow1 = dtdatedisp.NewRow();
newRow1[0] = g.Order_Date;
newRow1[1] = g.totalQnty;
newRow1[2] = String.Format("{0:0.00}", g.totalTax);
newRow1[3] = String.Format("{0:0.00}", g.totalAmt);
dtdatedisp.Rows.Add(newRow1);
}
}
please see that there will be very less no of iterations....
is there any way ?? Can you Help me ??
There is a extension method called CopyToDataTable which is unfortunately on IEnumerable Data Row object. But with the use of following link, you can create/copy same extension method which will be called on any IEnumerable object And this would match your requirement.
Here is the link
With this you can directly write something like this in your code
drdatedisp.CopyToDataTable();
use CopyToDataTable(); Verified the result:
var results = (from myRow in myData.AsEnumerable()
where myRow.Field<double>("Num1") == 1
select myRow).CopyToDataTable();
DataTable dtTemp = (DataTable)results;
gvMain.DataSource = dtTemp;
I have this:
// Load changelog types
ChangeLogType[] Types = ChangeLogFunctions.GetAllChangelogTypes();
foreach(ChangeLogType Rec in Types){
ListItem N = new ListItem();
N.Text = Rec.Type;
N.Value = Rec.ID.ToString();
LstChangeLogType.Items.Add(N);
}
It calls a function that returns an array of ChangeLogTypes, and then adds each one into a list control. Is there a more elegant way of doing this? I feel I'm repeating code each time I do this or something similar.
Yup, LINQ to Objects is your friend:
var changeLogTypes = ChangeLogFunctions.GetAllChangelogTypes()
.Select(x => new ListItem {
Text = x.Type,
Value = x.ID.ToString() })
.ToList();
The Select part is projecting each ChangeLogType to a ListItem, and ToList() converts the resulting sequence into a List<ListItem>.
This is assuming you really wanted a new list with all these entries. If you need to add the results to an existing list, you'd do that without the ToList call, but calling AddRange on an existing list with the result of the Select call.
It's well worth learning more about LINQ in general and LINQ to Objects in particular - it can make all kinds of things like this much simpler.
var range = Types.Select(rec =>
new ListItem { Text = rec.Type, Value = rec.ID.ToString() });
LstChangeLogType.AddRange(range);
Linq?
LstChangeLogType.Items = Types.Select(x => new ListItem()
{ Text = x.Type, Value = x.ID.ToString() }).ToList();
using System.Linq;
var items = Types
.Select (rec => ListItem
{
Text = Rec.Type;
Value = Rec.ID.ToString();
}
LstChangeLogType.Items.AddRange(items);
Using some LINQ extension methods:
LstChangeLogType.AddItems.AddRange(
Types.Select(t =>
new ListItem() { Text = t.Type, Value = t.ID.ToString() }).ToArray());
I have a datatable which contains a load of dates. I wanted to group these by date and give each row a count.
I have managed to do this by dong the following:
IEnumerable query = from row in stats.AsEnumerable()
group row by row.Field<string>("date") into grp
select new { Date = grp.Key, Count = grp.Count(t => t["date"] != null) };
(where "stats" is the datatable)
I can see from debugging that this brings back the values all grouped as I need, but now I need to loop them and get each date and count.
My problem is I don't know how to retrieve the values!
I have a foreach loop
foreach (var rw in query)
{
string date = rw.Date; // <---- this is my problem?
}
I don't know what type my Ienumerable is to be able to reference the values in it!
So my question is how can I retrieve each date and count for each row by doing similar to the above?
I hope this makes sense!
This link on my blog should help you
http://www.matlus.com/linq-group-by-finding-duplicates/
Essentially your type is an anonymous type so you can't reference it as a type but you can access the properties like you're trying to do.
I think I see your issue. If you're trying to return it from a method, you should define a type and reuturn it like shown below:
public IEnumerable<MyType> GetQuery()
{
var query = from row in stats.AsEnumerable()
group row by row.Field<string>("date") into grp
select new { Date = grp.Key, Count = grp.Count(t => t["date"] != null) };
foreach (var rw in query)
{
yield return new MyType(rw.Date, rw.Count);
}
}
declare your "query" variable using "var" as shown above.
I guess you don't have access to the properties of the anonymous class because you're using IEnumerable query = .... Try var query = ... instead.
Going by your comment "I am returning the query from a function", which I take to mean that you want to do the query in a method, return the data to the caller, and then iterate the data in the caller, I suggest you return a Dictionary<DateTime, int>, like this:
static Dictionary<DateTime, int> GetSummarisedData()
{
var results = (
from row in stats.AsEnumerable()
group row by row.Field<string>("date") into grp
select new { Date = grp.Key, Count = grp.Count(t => t["date"] != null) })
.ToDictionary(val => val.Date, val => val.Count);
return results;
}
then in the caller you can just
foreach (var kvp in GetSummarisedData())
{
// Now kvp.Key is the date
// and kvp.Value is the count
}