select more column not in group by using linq in c# - asp.net

cmd = new SqlCommand(" ", con);
da = new SqlDataAdapter(cmd);
DataTable t_eight = new DataTable("t_eight");
da.Fill(t_eight); //databale "t_eight" fill
//linq query
var query3 = (from a in t_eight.AsEnumerable() //t_eigth Databale
group a by new
{ //Group by with condition
IdendityName = a.Field<String>("Idendity Name"),
ContactPersonName = a.Field<String>("Contact Person Name"),
CustomerName = a.Field<String>("Customer Name")
}
into g
select new
{
IdendinyName = g.Key.IdendityName,
ContactPersonName = g.Key.ContactPersonName,
CurtomerName = g.Key.CustomerName,
TotalBook = g.Sum(x => x.Field<Int32>("Total Book Quantity")
+ x.Field<Int32>("Quatan Book Qty")
- x.Field<Int32>("Return Book Quality"))
});
GridView1.DataSource = query3;
GridView1.DataBind();
Datatable contains columns Identity Name, customer Name, customer Contact Name, Total Book Quantity, Return Book Quality, and Quatan Book Qty.
Group by contains three column Identity Name, customer Name, and customer Contact Name
New column in select statement Total Book contains ( total book quant+Quatan Book Qty-Return Book Quality). I want all columns in the gridview but the grid contains Identity Name, customer Name, customer Contact Name, and total book columns
How can I do this?
Dataset table "t_eight"
Gridview missing column Quatan Book and Return Book

Assuming you expect the additional fields to be identical once the rows are grouped, you just need to pick a random row from the group to get the values - the First row should work.
var query3 = (from a in t_eight.AsEnumerable()//t_eigth Databale
group a by new
{//Group by with condition
IdendityName = a.Field<String>("Idendity Name"),
ContactPersonName = a.Field<String>("Contact Person Name"),
CustomerName = a.Field<String>("Customer Name")
}
into g
select new {
g.Key.IdendityName,
g.Key.ContactPersonName,
g.Key.CustomerName,
ReturnBookQuality = g.First().Field<Int32>("Return Book Quality"),
QuatanBookQty = g.First().Field<Int32>("Quatan Book Qty"),
TotalBook = g.Sum(x => x.Field<Int32>("Total Book Quantity")
+ x.Field<Int32>("Quatan Book Qty") - x.Field<Int32>("Return Book Quality"))
}
);
Note: I removed the redundant member names from the anonymous type, I don't see any reason to put them there.

If I understand you correctly, you want to see the totals of three columns besides the calculated TotalBook column. Here's how you can do that:
var query3 = (from a in t_eight.AsEnumerable()
group a by new
{
IdendityName = a.Field<String>("Idendity Name"),
ContactPersonName = a.Field<String>("Contact Person Name"),
CustomerName = a.Field<String>("Customer Name")
}
into g
let tbq = g.Sum(x => x.Field<Int32>("Total Book Quantity"))
let qbq = g.Sum(x => x.Field<Int32>("Quatan Book Qty"))
let rbq = g.Sum(x => x.Field<Int32>("Return Book Quality"))
select new
{
IdendinyName = g.Key.IdendityName,
ContactPersonName = g.Key.ContactPersonName,
CurtomerName = g.Key.CustomerName,
TotalBookQuantity = tbq,
QuatanBookQuantity = qbq,
ReturnBookQuantity = rbq,
TotalBook = tbq + qbq - rbq
});
The three let statements collect the individual sums per grouping, after which you can use the variables tbq etc. multiple times.

Related

Find a vaule from columns of a dataset asp.net

I Want to find the value from dataset column Id.
here is the dataset
Id Value
1 football
2 Tennis
3 Cricket
If any one is absent in Column then i want to append that particular value in the dataset
I guess that is a DataTable inside a DataSet. First you need to query if the id is in the DataTable:
var dataTable = dataSet.Tables[0]; //For this example I'm just getting the first DataTable of the DataSet, but it could be other.
var id = 1;
var value = "football";
//Any(...) will return true if any record matches the expression. In this case, the expression is if a Id Field of the row is equals to the provided id
var contained = dataTable.AsEnumerable().Any(x =>x.Field<int>("Id") == id);
Then, if it's not there, add a new row:
if(!contained)
{
var row = dataTable.NewRow();
row["Id"] = id;
row["Value"] = value;
dataTable.Rows.Add(row);
}
Hope it helps
First you should use a loop to see if your dataset column 'id' contains the value. If the id is not existing then:
DataRow newrow = ds.Tables[0].NewRow(); //assuming ds is your dataset
newrow["id"] = "your new id value";
newrow["value"] = "your new value";
ds.Tables[0].Rows.Add(newrow);

Why is my query not returning distinct rows?

Afternoon,
I am trying to return a list of products from my SQL Server 2008 R2 database but I only want to return the results with the latest date.
However the code below seems to return all items, even the ones with an older date. How do I go about getting my results with just the latest date.
var query = (from a in dc.aboProducts
join t in dc.twProducts on a.sku equals t.sku
join lp in dc.LowestPrices on a.asin equals lp.productAsin
select new GetLowestPrices
{
productAsin = lp.productAsin,
sku = t.sku,
title = t.title,
twprice = Convert.ToString(t.twPrice),
lowprice = Convert.ToString(lp.price),
amzprice = Convert.ToString(lp.tweAmzPrice),
lastupdated = Convert.ToDateTime(lp.priceDate)
}).Distinct().OrderBy(ti => ti.title);
return query.ToList();
Try something like this:
var query =
from a in dc.aboProducts
join t in dc.twProducts on a.sku equals t.sku
join lp in dc.LowestPrices on a.asin equals lp.productAsin
select new GetLowestPrices
{
productAsin = lp.productAsin,
sku = t.sku,
title = t.title,
twprice = Convert.ToString(t.twPrice),
lowprice = Convert.ToString(lp.price),
amzprice = Convert.ToString(lp.tweAmzPrice),
lastupdated = Convert.ToDateTime(lp.priceDate)
};
var lookup =
query
.ToLookup(x => x.sku)
.Select(x => x.OrderByDescending(y => y.lastupdated).First())
.OrderBy(x => x.title);
return lookup.ToList();
Because the Distinct is not applied on the existing list, but create a new one, and you need to get it on a new list as:
val DistinctList = ExistingList.Distinct().ToList();

How to calculate count on of table column using group by clause in linq

I'm new to linq.
In c# I'm doing as follows to get the count of one column.
SELECT DispatcherName,
ActivityType,
CONVERT(BIGINT,COUNT(ActivityType)) AS Total
FROM ACTIVITYLOG
GROUP BY DispatcherName,
ActivityType
ORDER BY Total DESC
Can any one tell m,how I can achieve the same thing using LINQ.
Update:
HI I did as follows and got the reslut.
But I'm not able to convert result to datatable.
this is how I did.
here dt is datatabe with two columns Dispatchername and ActivityType.
var query1 = from p in dt.AsEnumerable()
group p by new
{
DispatcherName = p.Field<string>("Dispatchername"),
Activity = p.Field<string>("ActivityType"),
}
into pgroup
let count = pgroup.Count()
orderby count
select new
{
Count = count,
DispatcherName = pgroup.Key.DispatcherName,
Activity = pgroup.Key.Activity
};
pls help me out asap.
from c in ACTIVITYLOG
group c by new {c.DispatcherName, c.ActivityType} into g
orderby g.Count() descending
select new { g.Key.DispatcherName, g.Key.ActivityType, Total = g.Count() }
If you want your results returned back to a DataTable, one option is to use the CopyToDataTable method.
Here's a live example: http://rextester.com/XHX48973
This method basically requires you to create a dummy table in order to use its NewRow method - the only way to create a DataRow, which is required by CopyToDataTable.
var result = dt.AsEnumerable()
.GroupBy(p => new {
DispatcherName = p.Field<string>("DispatcherName"),
Activity = p.Field<string>("ActivityType")})
.Select(p => {
var row = dummy.NewRow();
row["Activity"] = p.Key.Activity;
row["DispatcherName"] = p.Key.DispatcherName;
row["Count"] = p.Count();
return row;
})
.CopyToDataTable();
Perhaps a better way might be just fill in the rows directly, by converting to a List<T> and then using ForEach.
DataTable dummy = new DataTable();
dummy.Columns.Add("DispatcherName",typeof(string));
dummy.Columns.Add("Activity",typeof(string));
dummy.Columns.Add("Count",typeof(int));
dt.AsEnumerable()
.GroupBy(p => new { DispatcherName = p.Field<string>("DispatcherName"),
Activity = p.Field<string>("ActivityType")})
.ToList()
.ForEach(p => {
var row = dummy.NewRow();
row["Activity"] = p.Key.Activity;
row["DispatcherName"] = p.Key.DispatcherName;
row["Count"] = p.Count();
dummy.Rows.Add(row);
});
Live example: http://rextester.com/TFZNEO48009
This should do the trick:
IList<ACTIVITYLOG> allActivityLogs;
var result = (from c in allActivityLogs
select new
{
DispatcherName = c.DispatcherName,
ActivityType = c.ActivityType,
Total = c.ActivityType.Count
}).OrderByDescending(x => x.Total)
.GroupBy(x => new { x.DispatcherName, x.ActivityType });
You only need to substitute the allActivityLogs collection with the actual collection of your entities.

Group using linq return datatable

i have a linq query that returns Articles ordered by the number of tags that match the current article
e.g
current article has tags - tag1, tag2, tag3
tagged article 1 - tag1,tag2,tag3
tagged article 2 - tag1,tag2
linq i have is
DataTable query = (from row in dt.AsEnumerable()
let tags = row.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries)
let count = tags.Count(t => currenttags.Contains(t))
orderby count descending
select row).CopyToDataTable();
i want to add the group by ClassName which is the article type (literature, case study, download etc)
so would be
group row by {row.Field<string>("ClassDisplayName")}
however when i add this to the query i get red sqiggles
DataTable query = (from row in dt.AsEnumerable()
group row by {row.Field<string>("ClassDisplayName")}
let tags = row.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries)
let count = tags.Count(t => currenttags.Contains(t))
orderby count descending
select row).CopyToDataTable();
any ideas what i'm doing wrong?
This is the current one that works with just the order by
DataTable dt = ArticleCollection(SqlClause.ToString());
var seperator = new[] { ",", " " };
var current = dr["Tags"].ToString();
var currenttags = dr.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries);
DataTable query = (from row in dt.AsEnumerable()
let tags = row.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries)
let count = tags.Count(t => currenttags.Contains(t))
orderby count descending
// group row by row.Field<string>("ClassDisplayName") into g
select row).CopyToDataTable();
if (!DataHelper.DataSourceIsEmpty(query))
{
TagRepeaterOutter.DataSource = query;
TagRepeaterOutter.DataBind();
}
If you are trying to order by count, and within each value of count, group the rows by ClassDisplayName, you can try this:
DataTable query = (from row in dt.AsEnumerable()
let tags = row.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries)
let count = tags.Count(t => currenttags.Contains(t))
let displayName = row.Field<string>("ClassDisplayName")
orderby count descending, displayName
select row).CopyToDataTable();
DataTable query = (from row in dt.AsEnumerable()
where (row.Field<string>("ClassDisplayName") == dr["ClassDisplayName"].ToString())
let tags = row.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries)
let count = tags.Count(t => currenttags.Contains(t))
orderby count descending
select row).CopyToDataTable();
IEnumerable<DataRow> types = (from row in dt.AsEnumerable()
group row by row.Field<string>("ClassDisplayName") into g
select g.FirstOrDefault());
DataTable dtType = types.CopyToDataTable();
and then another query on the inner nested repeater
DataTable query = (from row in dt.AsEnumerable()
where (row.Field<string>("ClassDisplayName") == dr["ClassDisplayName"].ToString())
let tags = row.Field<string>("Tags").Split(seperator, StringSplitOptions.RemoveEmptyEntries)
let count = tags.Count(t => currenttags.Contains(t))
orderby count descending
select row).CopyToDataTable();
anyone have a better solution let me know

how group by in Linq with 2 Field?

how group by in Linq with 2 Field ?
(from i in info
group i by i.OrderId into g
select new { orderId = g.Key, infos = g });
not only order by with order Id but with two field like ...
group by i.orderId And i.City
how this will do?
I believe you want something like this:
var result = from i in info
group i by new { OrderId = i.OrderId, City = i.City } into g
select new { OrderId = g.Key, Infos = g };
Creating the key as an anonymous type simply allows LINQ to use the default equality comparers for all the fields of the anonymous type, which should do the job in most situations.
As a follow-up to Noldorin's answer, you can omit the field names on the anonymous type when they match the fields you're setting them to.
Example:
var result = from i in info
group i by new { i.OrderId, i.City } into g
select new { OrderId = g.Key, Infos = g };
Another follow-up to the Noldorin's and Josh Einstein's answers...OrderID will take on the entire key...which in this case is a new object with two properties, OrderID and City. If your final result set needs the OrderID to be the OrderID, then you'll need to do the following:
var result = from i in info
group i by new { i.OrderId, i.City } into g
select new { OrderId = g.Key.OrderId, Infos = g };

Resources