I want to count the number of "d" in gridview using linq
My dataset is some thing like that :
public DataSet TitForTat()
{
DataSet ds = new DataSet();
DataTable dt = new DataTable("myt");
dt.Columns.Add(new DataColumn("iteration", typeof(int)));
dt.Columns.Add(new DataColumn("prison1", typeof(string)));
dt.Columns.Add(new DataColumn("prison2", typeof (string)));
prison[] prisons = new prison[2];
prisons[0] = new prison();
prisons[1] = new prison();
//---------------------------
DataRow dr = dt.NewRow();
prisons[0]._state = "c";
prisons[1]._state = valueOfState[rd.Next(0, 1)];
dr["iteration"] = 0;
dr["prison1"] = "c";
dr["prison2"] = prisons[1]._state;
dt.Rows.Add(dr);
//----------------------
for (int i = 1; i <= _iteration; i++)
{
prisons[0]._state = prisons[1]._state;
prisons[1]._state = valueOfState[rd.Next(0, 2)];
DataRow dr1 = dt.NewRow();
dr1["iteration"] =i;
dr1["prison1"] = prisons[0]._state;
dr1["prison2"] = prisons[1]._state;
dt.Rows.Add(dr1);
}
ds.Tables.Add(dt);
return ds;
}
And in the form i have a grid view "gvData " :
gvData.DataSource = obj.TitForTat().Tables[0];
my gridview has a column "prison1" that sometimes is "d" and sometimes is "c" .
I need to count these iteration using linq;
You can use GroupBy:
var prisonGroups = ((DataTable)gvData.DataSource).AsEnumerable()
.GroupBy(row => row.Field<string>("prison1"));
int countC = prisonGroups
.Where(g => g.Key == "c")
.Sum(g => g.Count());
int countD = prisonGroups
.Where(g => g.Key == "d")
.Sum(g => g.Count());
Here's another approach:
DataTable source = (DataTable)gvData.DataSource;
int cPrisoners = source.AsEnumerable()
.Count(row => row.Field<string>("prison1") == "c");
int dPrisoners = source.AsEnumerable()
.Count(row => row.Field<string>("prison1") == "d");
Related
Hi I have created dynamic table as below and in that I have 2 rows with same id
How should I merge them.
DataTable dt = new DataTable();
dt = (DataTable)Session["AddtoCart"];
DataRow dr1 = dt.NewRow();
foreach (var key in collection.AllKeys)
{
dr1["Description"] = collection["hdDescription"];
dr1["Title"] = collection["hdTitle"];
dr1["ActualQuantity"] = collection["hdactualquantity"];
dr1["PropertyId"] = collection["hdPropertyId"];
dr1["Quantity"] = collection["Quantity"];
TempData["AddedtoCart"] = ConfigurationManager.AppSettings["AddtoCart"].ToString();
}
dt.Rows.Add(dr1);
My added rows are as
Propertyid, Quantity, ActualQuantity
1 5 10
1 2 10
2 3 20
2 4 20
Th result i needed is as
Propertyid, Quantity, ActualQuantity
1 7 10
2 7 20
Update: i have tried this answer:
var query = dt.AsEnumerable()
.GroupBy(row => row.Field<int>("PropertyId"))// issue over this line
.Select(grp => new
{
PropertyId = grp.Key,
Quantity = grp.Sum(row => row.Field<int>("Quantity")),
ActualQuantity = grp.First().Field<int>("ActualQuantity"),
Title = grp.First().Field<int>("Title"),
Description = grp.First().Field<int>("Description")
});
var SumByIdTable = dt.Clone();
foreach (var x in query)
SumByIdTable.Rows.Add(x.PropertyId, x.Quantity, x.ActualQuantity,x.Title, x.Description);
Session["AddtoCart"] = SumByIdTable;
but I am getting issue as Specified cast is not valid. on .GroupBy(row => row.Field("PropertyId"))
Update 2: I have tried below code but i am getting issue
DataTable dt = new DataTable();
dt.Columns.Add("PropertyId", typeof(int));
dt.Columns.Add("Quantity", typeof(int));
dt.Columns.Add("Description", Type.GetType("System.String"));
dt.Columns.Add("Title", Type.GetType("System.String"));
dt.Columns.Add("ActualQuantity", typeof(int));
DataRow dr1 = dt.NewRow();
foreach (var key in collection.AllKeys)
{
dr1["Description"] = collection["hdDescription"];
dr1["Title"] = collection["hdTitle"];
dr1["ActualQuantity"] = Convert.ToInt32(collection["hdactualquantity"]);
dr1["PropertyId"] = Convert.ToInt32(collection["hdPropertyId"]);
dr1["Quantity"] = Convert.ToInt32(collection["Quantity"]);
TempData["AddedtoCart"] = ConfigurationManager.AppSettings["AddtoCart"].ToString();
}
dt.Rows.Add(dr1);
var query = dt.AsEnumerable()
.GroupBy(row => row.Field<int>("PropertyId"))
.Select(grp => new
{
PropertyId = grp.Key,
Quantity = grp.Sum(row => row.Field<int>("Quantity")),
ActualQuantity = grp.First().Field<int>("ActualQuantity"),
Title = grp.First().Field<string>("Title"),
Description = grp.First().Field<string>("Description")
});
var SumByIdTable = dt.Clone();
foreach (var x in query)
SumByIdTable.Rows.Add(x.PropertyId, x.Quantity, x.ActualQuantity,x.Title, x.Description);
Session["AddtoCart"] = SumByIdTable;
but I am getting issue in
SumByIdTable.Rows.Add(x.PropertyId, x.Quantity, x.ActualQuantity,x.Title, x.Description);
Input string was not in a correct format.
Resolved Update 3: I have tried below code and is working
DataTable dt = new DataTable();
dt.Columns.Add("PropertyId", typeof(int));
dt.Columns.Add("Quantity", typeof(int));
dt.Columns.Add("Description", Type.GetType("System.String"));
dt.Columns.Add("Title", Type.GetType("System.String"));
dt.Columns.Add("ActualQuantity", typeof(int));
DataRow dr1 = dt.NewRow();
foreach (var key in collection.AllKeys)
{
dr1["Description"] = collection["hdDescription"];
dr1["Title"] = collection["hdTitle"];
dr1["ActualQuantity"] = Convert.ToInt32(collection["hdactualquantity"]);
dr1["PropertyId"] = Convert.ToInt32(collection["hdPropertyId"]);
dr1["Quantity"] = Convert.ToInt32(collection["Quantity"]);
TempData["AddedtoCart"] = ConfigurationManager.AppSettings["AddtoCart"].ToString();
}
dt.Rows.Add(dr1);
var query = dt.AsEnumerable()
.GroupBy(row => row.Field<int>("PropertyId"))
.Select(grp => new
{
PropertyId = grp.Key,
Quantity = grp.Sum(row => row.Field<int>("Quantity")),
ActualQuantity = grp.First().Field<int>("ActualQuantity"),
Title = grp.First().Field<string>("Title"),
Description = grp.First().Field<string>("Description")
});
var SumByIdTable = dt.Clone();
foreach (var x in query)
SumByIdTable.Rows.Add(Convert.ToInt32(x.PropertyId), Convert.ToInt32(x.Quantity), x.Description, x.Title, Convert.ToInt32(x.ActualQuantity));
Session["AddtoCart"] = SumByIdTable;
changes was I have to add the value in SumByIdTable as clone set in dt
You can use LINQ (-to-DataTable):
var query = dt.AsEnumerable()
.GroupBy(row => row.Field<int>("Propertyid"))
.Select(grp => new {
Propertyid = grp.Key,
Quantity = grp.Sum(row => row.Field<int>("Quantity")),
ActualQuantity = grp.First().Field<int>("ActualQuantity")
});
var SumByIdTable = dt.Clone();
foreach(var x in query)
SumByIdTable.Rows.Add(x.Propertyid, x.Quantity, x.ActualQuantity);
Below is the method that i used to display records based on the conditions.
I have so many rows inserted in database and the data should be displayed in such a way that:
for the first grid i need to bind from A00-B99
for the second grid bind from c00-d49
for the third grid bind from d50-d89
for the fourth grid bind from E00-E89
like that i have so many grids that which i should bind the data but it is not working.
public void BindGrid()
{
string query = "select * from tablename";
SqlDataAdapter da = new SqlDataAdapter(query, conn);
DataSet ds = new DataSet();
da.Fill(ds);
DataTable dt = ds.Tables[0];
Session["dt1"] = dt;
DataTable dt2 = (DataTable)Session["dt1"];
DataRow[] dr = dt2.Select("Text >='A%' AND Text >='B%' OR Text ='C%'");
DataTable Newdt = dr.CopyToDataTable<DataRow>();
grd1.DataSource = Newdt;
grd1.DataBind();
}
What happens is the data that starts with A and B in the text column gets eliminated and from c to z gets binded to my first grid but the series with A and B should get binded to first grid and series C and D should get binded to second grid ie(c00-d49) and the series that are remaining in D should get binded to third grid(ie D50-D89) and series E should get binded to fourth grid(ie E00-E89) like that it should be done.
How can i do this?
I suggest you filter ranges out of your initial DataTable and assign each range to a new DataTable. Here is an example, of course you will continue to query for your data, but I have built the data manually for demonstration. Also shared as LinqPad Query
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Code", Type.GetType("System.String")));
DataRow r = dt.NewRow();
r[0] = "A00";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "B50";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "B99";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "c00";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "c30";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "c49";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "c50";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "d59";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "d50";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "d60";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "d89";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "E00";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "E50";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "E89";
dt.Rows.Add(r);
r = dt.NewRow();
r[0] = "E90";
dt.Rows.Add(r);
var range1 = dt.AsEnumerable().Where (d => d[0].ToString().CompareTo("A") >= 0 && d[0].ToString().CompareTo("B99") <= 0);
DataTable TableRange1 = range1.CopyToDataTable();
var range2 = dt.AsEnumerable().Where (d => d[0].ToString().CompareTo("c00") >= 0 && d[0].ToString().CompareTo("d49") <= 0);
DataTable TableRange2 = range2.CopyToDataTable();
var range3 = dt.AsEnumerable().Where (d => d[0].ToString().CompareTo("E00") >= 0 && d[0].ToString().CompareTo("E89") <= 0);
DataTable TableRange3 = range3.CopyToDataTable();
I have one news repeater that show two fields like News_Text and News_Date.
Here I just want to display this data with group by News_date.
like:
12/24/2013
test
test1
test 2
11/12/213
blah..blah
here is my code:
private void BindNewsRepeater()
{
using (DataClassesDataContext db = new DataClassesDataContext())
{
var query = from n in db.News
orderby n.News_date descending
select new
{
News_text = n.News_text,
News_date = n.News_date
};
DataSet myDataSet = new DataSet();
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("News_text", typeof(string)));
dt.Columns.Add(new DataColumn("News_date", typeof(string)));
foreach (var item in query)
{
DataRow dr = dt.NewRow();
dr["News_text"] = item.News_text.ToString();
dr["News_date"] = item.News_date.ToString("dd/MM/yyyy");
dt.Rows.Add(dr);
}
myDataSet.Tables.Add(dt);
rpt_news.DataSource = myDataSet;
rpt_news.DataBind();
}
}
and my repeater design code is:
<asp:Repeater ID="rpt_news" runat="server" onitemdatabound="rpt_news_ItemDataBound">
<ItemTemplate><asp:Label ID="lbl_news_date" runat="server"><%#Eval("News_date")%></asp:Label><br />
<asp:Label ID="lbl_news_text" runat="server"><%#Eval("News_text")%></asp:Label>
</ItemTemplate>
<SeparatorTemplate><br/><br/></SeparatorTemplate>
</asp:Repeater>
You can simply GroupBy News_date, then select for each key of News_date a list of News_Text. Something like this:
var results = News
.GroupBy(n => n.News_date)
.Select(g => new {
NewsDate = g.Key,
NewsTexts = g.Select(x => x.News_Text)
});
This will return a list of News_Text for each NewsDate.
var query = db.News
.OrderBy(n => n.News_date)
.GroupBy(n => n.News_date, n => n.News_text);
foreach (var g in query)
{
foreach(var t in g)
{
DataRow dr = dt.NewRow();
dr["News_text"] = t.ToString();
dr["News_date"] = g.Key.ToString("dd/MM/yyyy");
dt.Rows.Add(dr);
}
}
I'm using datatable that has two columns of text data, I just want to do abbreviations expanding for each row, so I used Dictionary and here it is a sample of my code:
private void ExpandWords()
{
DataTable DT = new DataTable();
DataRow Row;
DT.Columns.Add(new System.Data.DataColumn("Name", typeof(string)));
DT.Columns.Add(new System.Data.DataColumn("Label", typeof(string)));
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("emp", "employee");
dict.Add("dep", "department");
for (int i = 0; i < dataGridView6.Rows.Count; i++)
{
Row = DT.NewRow();
foreach(KeyValuePair<string,string> rep in dict)
{
Row[0] = dataGridView6.Rows[i].Cells[0].Value.ToString().Replace (rep.Key, rep.Value);
Row[1] = dataGridView6.Rows[i].Cells[1].Value.ToString().Replace (rep.Key, rep.Value);
}
DT.Rows.Add(Row);
dataGridView7.DataSource = DT;
}
it can be run without exceptions but it doesn't work
Why do you enumerate the dictionary in the loop of the grid-rows? Just lookup the key.
You also have to add each row in the loop, not outside, otherwise you just add the last row:
for (int i = 0; i < dataGridView6.Rows.Count; i++)
{
Row = DT.NewRow();
string abbrCell1 = dataGridView6.Rows[i].Cells[0].Value.ToString();
string abbrCell2 = dataGridView6.Rows[i].Cells[1].Value.ToString();
Row[0] = dict[abbrCell1];
Row[1] = dict[abbrCell2];
DT.Rows.Add(Row);
}
Edit If you want to replace all abbreviated words in the string of the datagrid cells with the not-abbreviated word in the dictionary you can use this code:
// in the loop
Row = DT.NewRow();
string abbrCell1 = dataGridView6.Rows[i].Cells[0].Value.ToString();
string abbrCell2 = dataGridView6.Rows[i].Cells[1].Value.ToString();
IEnumerable<string> unabbrWords1 = abbrCell1.Split()
.Select(w => dict.ContainsKey(w) ? dict[w] : w);
IEnumerable<string> unabbrWords2 = abbrCell2.Split()
.Select(w => dict.ContainsKey(w) ? dict[w] : w);
Row[0] = string.Join(" ", unabbrWords1);
Row[1] = string.Join(" ", unabbrWords2);
DT.Rows.Add(Row);
You should change it a bit otherwise you'll have same value overwritten in loop:
var value1 = dataGridView6.Rows[i].Cells[0].Value.ToString();
var value2 = dataGridView6.Rows[i].Cells[1].Value.ToString();
foreach (KeyValuePair<string, string> rep in dict)
{
value1 = value1.Replace(rep.Key, rep.Value);
value2 = value2.Replace(rep.Key, rep.Value);
}
DT.Rows.Add(value1, value2);
You're also missing DataBind() if you're using Web Forms at the end
dataGridView7.DataSource = DT;
dataGridView7.DataBind();
mz
I have a datatable with 10 columns, but User can select the columns to be displayed so I need to create a generic code to display only the selected columns.
Current code:
string[] selectedColumns = new[] { };
DataTable columns = new DataView(table).ToTable(false, selectedColumns);
You could simply hide the columns in the datagridview (supposing you're using one)
dataGridView1.Columns["ColName"].Visible = False;
for every column that are not in selectedColumns
But if you really need to filter the dataset, I remember that you can do something like:
mydatatable.Columns.Remove("ColName");
in your datatable... or in a copy.
If you are going to show the columns in a datagridview, my option will be setting the ColumnMapping property of the datatable column like this
mydatatable.Columns["Colname"].ColumnMapping = MappingType.Hidden;
Unfortunatly I'm not at home now, so I can't test it, but as you can see, there are many options.
EDIT: In response to your request, you can deal with non selected columns like this:
for(int i = 0;i<dt.Columns.Count;i++)
{
if(!selectedColumns.Contains(dt.Columns[i].ColumnName))
{
dt.Columns[i].ColumnMapping = MappingType.Hidden;
}
}
public static void Main(string[] args)
{
DataTable act = new DataTable();
act.Columns.Add(new DataColumn("id", typeof(System.Int32)));
act.Columns.Add(new DataColumn("name"));
act.Columns.Add(new DataColumn("email"));
act.Columns.Add(new DataColumn("phone"));
DataRow dr = act.NewRow();
dr["id"] = 101;
dr["name"] = "Rama";
dr["email"] = "rama#mail.com";
dr["phone"] = "0000000001";
act.Rows.Add(dr);
dr = act.NewRow();
dr["id"] = 102;
dr["name"] = "Talla";
dr["email"] = "talla#mail.com";
dr["phone"] = "0000000002";
act.Rows.Add(dr);
dr = act.NewRow();
dr["id"] = 103;
dr["name"] = "Robert";
dr["email"] = "robert#mail.com";
dr["phone"] = "0000000003";
act.Rows.Add(dr);
dr = act.NewRow();
dr["id"] = 104;
dr["name"] = "Kevin";
dr["email"] = "kevin#mail.com";
dr["phone"] = "0000000004";
act.Rows.Add(dr);
dr = act.NewRow();
dr["id"] = 106;
dr["name"] = "TomChen";
dr["email"] = "tomchen#mail.com";
dr["phone"] = "0000000005";
act.Rows.Add(dr);
var lselColumns = new[] {"id", "name"};
var dt = act.DefaultView.ToTable(true, lselColumns);
foreach (DataRow drow in dt.Rows)
{
string drowData = string.Empty;
foreach (DataColumn r in drow.Table.Columns)
{
drowData += (drowData == string.Empty) ? drow[r] : "|" + drow[r];
}
Console.WriteLine(drowData);
}
Console.ReadLine();
}