I am new to C# and ASP .NET programming. I am making a crystal report in .net. I setup Dataset and DataTable. For report sources.
I am getting data from a linq query. and after that I am populating them in a instance of Dataset. I use debugger and it shows that I have data from the query. But my crystal reeport just shows the column heading not the column data.
Here is my code:
private void ViewReport()
{
DataSet1 Dataset = new DataSet1();
DataTable rptTable = Dataset.Tables["Emp_info"];
DataTable rptTab = Dataset.Tables["Attendance_table"];
Ind_attendance_rpt rptAtd = new Ind_attendance_rpt();
DataRow dataRow1; // declaring Row of dataset
DataRow dataRow2;
//IndividualAttendance rptAtt = new IndividualAttendance();
var rport = from att in db.Attendance_tables
join emp in db.Emp_infos on att.Login_id equals emp.ID
orderby att.Id
select new
{
att.Id,
emp.Emp_name,
emp.ID,
emp.Designation,
emp.Dept,
att.Entry_time,
att.Exit_time,
att.Status,
att.Date
};
Dataset.Tables["Emp_info"].Clear();
Dataset.Tables["Attendance_table"].Clear();
foreach (var rt in rport)
{
dataRow1 = rptTable.NewRow();
dataRow2 = rptTab.NewRow();
dataRow2["Id"] = rt.Id;
dataRow1["Emp_name"] = rt.Emp_name;
dataRow1["Designation"] = rt.Designation;
dataRow1["Dept"] = rt.Dept;
dataRow2["Entry_time"] = rt.Entry_time;
dataRow2["Exit_time"] = rt.Exit_time;
dataRow2["Status"] = rt.Status;
dataRow2["Date"] = rt.Date;
dataRow2["Login_id"] = rt.ID;
Dataset.Tables["Emp_info"].Rows.Add(dataRow1);
Dataset.Tables["Attendance_table"].Rows.Add(dataRow2);
}
rptAtd.SetDataSource(Dataset);
CrystalReportViewer1.ReportSource = rptAtd;
}
Can anyone tell me the reason?
Here is the result I am getting right now:
Debug Image:
Try to call Refresh on the report after setting the ReportSource
CrystalReportViewer1.Refresh();
you may have to use ToList() on your linq as well;
Related
I have this project on c# windows forms and what I have to do is get some data from a web service and present them to FastRaport.
I have tried display them on a DataGridView first and then fetching the data from it and it works pretty nice. I can download the file and then it gives me a dialog asking me in what format do I want to save it.
But now the requirement is to not use gridview at all, just a button that would convert directly those data into a PDF file.
Here's my code for displaying the data into DataGridView:
var asd1 = dataGridView1.Columns.Add("DrzavaAng", "DrzavaAng");
var asd2 = dataGridView1.Columns.Add("Valuta", "Valuta");
var asd3 = dataGridView1.Columns.Add("Oznaka", "Oznaka");
var asd4 = dataGridView1.Columns.Add("Nomin", "Nomin");
var asd5 = dataGridView1.Columns.Add("Sreden", "Sreden");
for (var i = 0; i<xmlNodes.Count; i++)
{
var node = xmlNodes[i];
var states = new Class();
states.Valuta = node["Valuta"].InnerText;
states.Oznaka = node["Oznaka"].InnerText;
states.Nomin = node["Nomin"].InnerText;
states.Sreden = node["Sreden"].InnerText;
states.DrzavaAng = node["DrzavaAng"].InnerText;
//var asd = dataGridView1.Columns.Add("1", "1");
_ = dataGridView1.Rows.Add();
dataGridView1.Rows[i].Cells["DrzavaAng"].Value=states.DrzavaAng;
dataGridView1.Rows[i].Cells["Valuta"].Value=states.Valuta;
dataGridView1.Rows[i].Cells["Oznaka"].Value=states.Oznaka;
dataGridView1.Rows[i].Cells["Nomin"].Value=states.Nomin;
dataGridView1.Rows[i].Cells["Sreden"].Value=states.Sreden;
}
Here's the part where I pass the data from GridView to the FastReport "database".
using (Report report = new Report())
{
report.Load(ReportPath);
DataTable dt = new DataTable();
foreach (DataGridViewColumn cl in dataGridView1.Columns)
{
dt.Columns.Add();
}
object[] clvl = new object[dataGridView1.Columns.Count];
foreach (DataGridViewRow row in dataGridView1.Rows)
{
for (int i = 0; i<row.Cells.Count; i++)
{ clvl[i] = row.Cells[i].Value; }
dt.Rows.Add(clvl);
}
DataSet ds = new DataSet();
ds.Tables.Add(dt);
report.Dictionary.RegisterData(ds.Tables[0], "test", true);
report.SetParameterValue("date", dateTimePicker1.Value.ToString("dd.MM.yyyy"));
report.Show();
}
Here's my FastReport file before committing anything:
FastReportImage
And here's the output I get : FastReport output
My question is, how can I make it to fetch the data without the gridview, directly from webservice and load it into a FastReport -> PDF file?
This is the first time I am using DataSet. Below is my code
var transactionSet = new ModelExecutionContext()
{
TransactionSet = new DataSet()
{
Tables = { new DataTable()
{
TableName = "transaction_history"
}
}
}
};
transactionSet.TransactionSet.Tables["transaction_history"].Columns.Add().ColumnName = "retailer_reference_id";
var retailerReferenceIdRow = transactionSet.TransactionSet.Tables["transaction_history"].NewRow();
retailerReferenceIdRow["retailer_reference_id"] = 8;
transactionSet.TransactionSet.AcceptChanges();
I am unit testing a method in a class which has the datasets. I am trying to mock those datasets. I thought transactionSet.TransactionSet.AcceptChanges(); will save the changes into the DataSet, but in the execution, I am getting context?.TransactionSet?.Tables["transaction_history"]?.Rows.Count = 0
Is anything incorrect with my code?
After you created object of row you need to add row to table.
transactionSet.TransactionSet.Tables["transaction_history"].Rows.Add(retailerReferenceIdRow);
I am trying to learn how to join two data tables into one using Linq. My linq query is working correctly and I can see expected values in it. However, when I loop the linq results, and assign the values to a newly created data row and add that row to a new data table, the rows come out empty.
Here is my code:
private void btnCombine_Click(object sender, EventArgs e)
{
var innerJoinQuery =
from strRow in StrDataTable.AsEnumerable()
join intRow in IntDataTable.AsEnumerable()
on strRow.Field<int>("IntID") equals intRow.Field<int>("ID")
select new {
IntOne = intRow.Field<int>("FirstNum"),
IntTwo = intRow.Field<int>("SecondNum"),
StrOne = strRow.Field<string>("FirstStr"),
StrTwo = strRow.Field<string>("SecondStr"),
StrThree = strRow.Field<string>("SecondStr")
};
DataTable newTable = new DataTable();
newTable.Columns.Add("IntOne");
newTable.Columns.Add("IntTwo");
newTable.Columns.Add("FirstStr");
newTable.Columns.Add("SecondStr");
newTable.Columns.Add("ThirdStr");
newTable.Columns["IntOne"].DataType = System.Type.GetType("System.String");
newTable.Columns["IntTwo"].DataType = System.Type.GetType("System.String");
newTable.Columns["FirstStr"].DataType = System.Type.GetType("System.String");
newTable.Columns["SecondStr"].DataType = System.Type.GetType("System.String");
newTable.Columns["ThirdStr"].DataType = System.Type.GetType("System.String");
foreach (var row in innerJoinQuery)
{
DataRow rowToAdd = newTable.NewRow();
rowToAdd.ItemArray[0] = row.IntOne.ToString();
rowToAdd.ItemArray[1] = row.IntTwo.ToString();
rowToAdd.ItemArray[2] = row.StrOne.ToString();
rowToAdd.ItemArray[3] = row.StrTwo.ToString();
rowToAdd.ItemArray[4] = row.StrThree.ToString();
newTable.Rows.Add(rowToAdd);
}
dataGridView3.DataSource = newTable;
}
Using DataRow.ItemArray property with individual values doesn't work - instead, create the object[] array and then set the whole thing to the .ItemArray property. See this MSDN page for additional examples.
foreach (var row in innerJoinQuery)
{
DataRow rowToAdd = newTable.NewRow();
object[] items = new object[] {
row.IntOne.ToString(),
row.IntTwo.ToString(),
row.StrOne.ToString(),
row.StrTwo.ToString(),
row.StrThree.ToString()
};
rowToAdd.ItemArray = items;
newTable.Rows.Add(rowToAdd);
}
Alternately, use the DataRow indexer directly, which works with individual columns:
rowToAdd[0] = row.IntOne.ToString();
rowToAdd[1] = row.IntTwo.ToString();
rowToAdd[2] = row.StrOne.ToString();
rowToAdd[3] = row.StrTwo.ToString();
rowToAdd[4] = row.StrThree.ToString();
Additionally, when creating columns, there is a constructor that takes the type which can save you some code. Your first two column types are mismatched.
newTable.Columns.Add("IntOne", typeof(int));
newTable.Columns.Add("FirstStr", typeof(string));
The first two values appear to be Integers:
IntOne = intRow.Field<int>("FirstNum"),
IntTwo = intRow.Field<int>("SecondNum"),
But the DataType you assign the columns to is String:
newTable.Columns["IntOne"].DataType = System.Type.GetType("System.String");
newTable.Columns["IntTwo"].DataType = System.Type.GetType("System.String");
Update those to int's and see if that resolves it:
newTable.Columns["IntOne"].DataType = System.Type.GetType("System.Int32");
newTable.Columns["IntTwo"].DataType = System.Type.GetType("System.Int32");
rowToAdd.ItemArray[0] = row.IntOne;
rowToAdd.ItemArray[1] = row.IntTwo;
You may also need to supply the DataPropertyName for the columns:
newTable.Columns["IntOne"].DataPropertyName = "FirstNum";
newTable.Columns["IntTwo"].DataPropertyName = "SecondNum";
...
And ensure that the AutoGenerateColumns value is set to false
dataGridView3.AutoGenerateColumns = false;
First time I've worked with LINQ, and I've encountered a strange problem. I'm using MS SQL 2008. If I alter a row and SubmitChanges(), I can see the changes in the SQL Server Management Studio, but when I query to refill my dataGridViews with the updated information, I get the old version of the data.
Below is a change in my data:
if (textBox1.Text.Length > 1)
{
var query = from eq in db.equipments
where eq.SerNo == serial
select eq;
foreach (equipment equip in query)
{
equip.Loc = textBox1.Text;
equip.Owner = "Evisive";
equip.Status = updatedStatus;
equip.SystemName = "";
}
db.SubmitChanges();
}
else
{
MessageBox.Show("Enter a Destination");
}
Again, that part works (changes the data in the database). Below is where I try to update the table (the part that doesn't seem to work):
public void Update_EquipmentGrid()
{
BindingSource b = new BindingSource();
b.DataSource = from eq in db.equipments
select eq;
dataGridView2.DataSource = b;
}
Is this not the right way to update a table?
Figured it out. This link explains it.
http://msdn.microsoft.com/en-us/library/Bb386982(v=vs.110).aspx
Code should be:
InventoryDataContext dba = new InventoryDataContext();
BindingSource b = new BindingSource();
b.DataSource = from eq in dba.equipments
select eq;
dataGridView2.DataSource = b;
Not sure why, but you need to create a new instance of the DataContext each time it is updated.
Try
dataGridView2.DataSource = null;
before
dataGridView2.DataSource = b;
Also try converting your data to list before assigning.
b.DataSource = (from eq in db.equipments
select eq).ToList();
maybe this helps you
https://www.devexpress.com/Support/Center/Question/Details/Q142798
example:
var orders = DBInterface.dcAPI.OrderInfos;
var b = orders.GetNewBindingList();
dgOrders.ItemsSource = b;
Would someone kindly assist me with the following? I have two DataGridView objects that each display a DataTable, where the two datatables are related with the following code:
DataSet dSet = new DataSet();
DataTable ParentList = ListToDataTable(_listOfAllAlbumObjects);
DataTable ChildList = ListToDataTable(_listOfAllTrackObjects);
dSet.Tables.AddRange(new DataTable[]{ParentList, ChildList});
DataColumn parentRelationColumn = ParentList.Columns["AlbumId"];
DataColumn childRelationColumn = ChildList.Columns["AlbumId"];
dSet.Relations.Add("ParentToChild", parentRelationColumn, childRelationColumn);
ParentDataGridView.DataSource = dSet;
ParentDataGridView.DataMember = "ParentList";
ChildDataGridView.DataSource = ???;
ChildDataGridView.DataMember = "ParentToChild";
Both DataTables are actually List<> converted to DataTables with the following:`
public static DataTable ListToDataTable<T>( IList<T> data)
{
var props = TypeDescriptor.GetProperties(typeof(T));
var table = new DataTable();
for (var i = 0; i < props.Count; i++)
{
PropertyDescriptor prop = props[i];
table.Columns.Add(prop.Name, prop.PropertyType);
}
var values = new object[props.Count];
foreach (T item in data)
{
for (int i = 0; i < values.Length; i++)
{ values[i] = props[i].GetValue(item); }
table.Rows.Add(values);
}
return table;
}
Initially it appears that the each DataGridView displays the data appropriately; however the child DataGridView does not update with any change of record in the parent DataGridView.
I see that the tables need to be interconnected through the binding-source; however I don't believe there is a true binding-source here.
Could someone please steer me in the right direction? Thanks.
There's an MSDN article showing what you want to do:
How to: Create a Master/Detail Form Using Two Windows Forms DataGridView Controls
Here's how this might work for you:
Either through the designer or through code add two BindingSources to your project: parentBindingSource and childBindingSource. Then try this in place of the code you have.
// Associate your BSs with your DGVs.
ParentDataGridView.DataSource = parentBindingSource;
ChildDataGridView.DataSource = childBindingSource;
// (Most of) your code here:
DataSet dSet = new DataSet();
DataTable ParentList = ListToDataTable(_listOfAllAlbumObjects);
DataTable ChildList = ListToDataTable(_listOfAllTrackObjects);
dSet.Tables.AddRange(new DataTable[]{ParentList, ChildList});
DataColumn parentRelationColumn = ParentList.Columns["AlbumId"];
DataColumn childRelationColumn = ChildList.Columns["AlbumId"];
dSet.Relations.Add("ParentToChild", parentRelationColumn, childRelationColumn);
// Let's name this DT to make clear what we're referencing later on.
ParentList.TableName = "ParentListDT";
// Rather than set the data properties on your DGVs, set them in your BindingSources.
parentBindingSource.DataSource = dSet;
parentBindingSource.DataMember = "ParentListDT";
childBindingSource.DataSource = parentBindingSource;
childBindingSource.DataMember = "ParentToChild";