I have a datatable with following structure:
Department | DocumentID | Days
Before I add rows to this datatable I should consider two situations:
If Department and DocumentID already exists, update number of Days in same row.
else add row.
Example:
Instead of multiple records for same Department and DocumentID
Marketing | 1 | 10
Human Resources | 1 | 5
Marketing | 1 | 5
Marketing | 2 | 5
Should add number of days to existing row
Marketing | 1 | 15
Human Resources | 1 | 5
Marketing | 2 | 5
If this is not easily doable, I thought of adding multiple records to one table and then sum days where Department and DocumentID are the same, but I didn't succeed in doing this also.
Any tips?
You can search your datatable with the Select method which use a SQL like syntax for the filtering.
Then either insert a new row or update the one you found.
var rows = dataTable.Select(string.Format("DocumentId = {0}", documentId));
if (rows.Length == 0)
{
// Add your Row
}
else
{
// Update your Days
rows[0]["Days"] = newDayValue;
}
Related
I have my data arranged in two related tables (SQLite). Let's say table Families and People. Table structure looks like below.
CREATE TABLE families (
FamilyID INTEGER PRIMARY KEY AUTOINCREMENT,
FamilyName VARCHAR,
FamilyPower INTEGER,
FamilyStatus Boolean
);
CREATE TABLE people (
PersonID INTEGER PRIMARY KEY AUTOINCREMENT,
FamilyID INTEGER REFERENCES families (FamilyID),
Name Varchar,
Age INTEGER
);
I'd like to display data from this table in grouped DataGrid. I can arrange this data as a DataSet, or as a custom class'es Objects or a netsted Objects (people could be a list of objects of class Person inside of the Family object). But I'm not sure which option is the best.
The worst option (I think) is doing one DataTable containing joined tables like SELECT * FROM families LEFT JOIN people ON families.FamilyID = people.PersonID. But I may be wrong and this is actually the best option to achieve what i want.
What I want is to display grouped data with group header containing full info about family and all its member as a data rows. So it would looks like below:
PersonID | Name | Age |
FamilyID: 1 Name: Stark Power: 10 Members: 3 Status: [x] <-- This is checkbox
1 | Eddard | 60 |
2 | Robb | 30 |
3 | Arya | 15 |
FamilyID: 2 Name: Lannister Power: 15 Members: 4 Status: [x]
4 | Cersei | 30 |
5 | Tyrion | 35 |
6 | Jaimie | 30 |
7 | Tywin | 30 |
FamilyID: 1 Name: Targaryen Power: 10 Members: 1 Status: [ ]
1 | Daenerys | 30 |
Is it even possible to achieve that? Please help me to choose best way to store data and solve how to bind and group it in the DataGrid?
Hi i am creating a form in c# using datagridview and i have a class Option
public class Option
{
public string Description;
public string scores;
}
So now i load multiple options into a datagridview and it looks like this
|Description|Scores|
A 1-2
B 3-4
C 5-6
D 7
I want to let the user be able to select the score just by clicking on the cell, but since one description can have 2 different scores the most i can do is make a seperate slider or checkbox area for them to select the score. What i wish to do is to split up the score cell into different rows depending on the score for that description. so 1 row in description might have 2 rows in the score column, is it possible? after that i will just use DGV.SelectedCell to retrieve and compute the score based on users selection
|Description|Score|
| | 1 |
| A |-----|
| | 2 |
|-----------------|
| | 3 |
| B |-----|
| | 4 |
|-----------------|
| | 5 |
| C |-----|
| | 6 |
|-----------------|
| D | 7 |
|-----------------|
EDIT my code
Dictionary<int,Option> Question = new Dictionary<int,option>();
//created dictionary of options for a question
DataTable DT = new DataTable();
DT.Columns.Add("Description");
DT.Columns.Add("Scores");
foreach (KeyValuePair<int, Option> item in Question)
{ DataRow dr = DT.NewRow();
Option Opt = item.Value;
dr["Description"] = opt.Description;
dr["Scores"] = opt.scores;
}
And then i just set the DGV source to the datatable
I'm on mobile and don't have an IDE so forgive me if this does not compile out of the box and you need to twerk it a bit to make it work:
string score = dr["Weightage"].Text; //save current value from "Weightage"
string[] scores = score.split('-'); //splits it into 2 parts
DT.Columns.Remove("Weightage"); //remove old column
DT.Columns.Add("WeightageA"); //create new columns
DT.Columns.Add("WeightageB");
dr["WeightageA"] = scores[0]; //set column values
dr["WeightageB"] = scores[1];
Let's say this is my table TicketUpdate in SQL Server with some data inside:
_______________________________
| Id | TicketId | Description |
-------------------------------
| 1 | 5 | desc1 |
| 2 | 6 | desc2 |
| 3 | 5 | desc3 |
| 4 | 5 | desc4 |
| 5 | 6 | desc5 |
I want to retrieve the last row with TicketId = 5 in using Petapoco.
There are several methods for retrieving single row like FirstOrDefault which looks like:
db.FirstOrDefault<TicketUpdate>("select * from TicketUpdate where TicketId = 5");
But using this statement it returns the first row with value of TicketId = 5 with a description of desc1.
My question is how can I retrieve the LastOrDefault value then? There is no such methods in Petapoco.
Additional info
Temporarily I can retrieve the last row with TicketId = 5 by nesting the query like
select *
from TicketUpdate
where Id = (select MAX(Id) from TicketUpdate where TicketId = 5)
But is there any methods or better approach for finding the last row like we retrieve First row by using FirstOrDefault method, without nesting the query?
As mentioned in the comments, you should be able to sort your data first.
Try something like this:
db.FirstOrDefault<TicketUpdate>("select TOP 1 * from TicketUpdate where TicketId = 5 orderby [Id] desc");
As long as Id is incremented it should return the last item added for TicketId == 5.
Change your query to get the last record where ID is max. Also you need to use Top 1 to get only one record.
select Top 1 * from TicketUpdate where TicketId = 5 order by ID desc
I have Datatable with Data. I called my postgres data base and get DataTable.
// get the new data from postgres
var dataTable = pg.GetDataTable("SELECT * FROM " + '"'+table+'"');
Now I need to remove specific Column. assume that there are 5 columns with data.
ID | Name | Address | Mobile | Home
_______________________________________________
1 | A |AAA | 123 | 345
2 | B |BBB | 234 | 456
3 | C |CCC | 345 | 567
So I need to remove "Home " DataColumn and Recreate this DataTable as following
ID | Name | Address | Mobile
____________________________________
1 | A |AAA | 123
2 | B |BBB | 234
3 | C |CCC | 345
How can I do this ?
Appreciate your comments.
Thanks
Just specify the columns you need explicitly rather than selecting unneeded columns and removing them afterwards:
SELECT "Id", "Name", "Address", "Mobile"
Using SELECT * is bad manners because it makes your contract with database unstable - should column configuration change you will get unpredictable result.
You just need to use the method DataTable.Columns.Remove(string name):
dataTable.Columns.Remove("Home");
Then the table doesn't contain this column anymore and all rows' data in this column is thrown away. However, omit this column in the first place and list the desired columns:
var dataTable = pg.GetDataTable("SELECT ID, Name, Address, Mobile FROM " + '"'+ table +'"');
Consider using
dataTable.Columns.Remove("ColumnName")
or
dataTable.Columns.RemoveAt(ColumnNumber)
Here is my problem. i have 3-5 persons that is going to set a grade on one person and they use their own individual row to do so, and what I'm having trouble to do is to sum and average the grade from individual data across multiple rows on the same table.
in the select new statement i have made a pseudo answer of what i want
var users = from workRew in db.Reviews
select new
{
UserID = workRew.UserID.DistinctOfSomeSort
AvgGrade = workRew.Grade.Sum/CountOfSomeSort
};
Here i a illustration.
So if i have this table
| SomeID | UserID | Grade |
| 1 | 2 | 3 |
| 2 | 3 | 1 |
| 3 | 2 | 1 |
And this is the output i want from the LINQ query on the above (In theory ateast)
| UserID | AvgGrade |
| 2 | 2 |
| 3 | 1 |
EDIT: Simplified the whole case, to a great extent.
It should look something like this fragment:
group by user.UserID
select new
{
User = user.UserID
TotGradeCount = workRew.Grade.Sum()
Graders = workRew.Grade.Count()
}