I have a class like so
class Person(){
int Id;
string Name;
string SomePersonalInfo;
}
and a datatable with columns being Id, Name, and SomePersonalInfo. I also have a collection housing data in a List.
List<Person> = new Id = 1, Name = "So So"
List<Person> = new Id = 1, SomePersonalInfo= "Something"
I am trying to use linq so I dont have multiple for each statements to add Name and SomePersonalInfo in the datatable or making unnessary steps like keep getting the datarow. ANy suggestions
If you already have a strongly typed list, why do you want to have a loosely typed DataTable at all? Also, there is no good way to create a DataTable via LINQ-query without having DataRows.
Therefore i would simply use a loop which is readable and efficient:
foreach(Person p in persons)
tblPerson.Rows.Add(p.Id, p.Name, p.SomePersonalInfo);
Update acc. comment:
no I already have the datatable I am just trying to update the
datatable from the collection
Then you have to find the intersection first, use Enumerable.Join:
var inBoth = from p in persons
join row in tblPersons.AsEnumerable()
on p.Id equals row.Field<int>("Id")
select new { Person = p, Row = row };
foreach(var b in inBoth)
{
b.Row.SetField("Name", b.Person.Name);
b.Row.SetField("SomePersonalInfo", b.Person.SomePersonalInfo);
}
Related
I would like to show list in datagridview, but having specific columns: GodinaUpisa, BrojIndeksa, Ime i Prezime, Ocena.
I get Ime i Prezime by overriding toString() in class Student.
This is short version of code. there is also while loop etc., citac=Reader, lista= new List<Polozio>() is returned after method is executed, everything working well except for the following part because I dont know how to do It.
SQL:
SELECT
*
FROM
TPolozio
INNER JOIN TStudent ON (TStudent.[BrojIndeksa] = TPolozio.[BrojIndeksa]) AND (TStudent.[GodinaUpisa] = TPolozio.[GodinaUpisa])
WHERE
SifraPredmeta="+p.SifraPredmeta+"
ORDER BY
TPolozio.GodinaUpisa
here is part of the code:
Student s = new Student();
s.GodinaUpisa = citac.GetInt32(0);
s.BrInd = citac.GetInt32(1);
s.Ime = citac.GetString(2);
s.Prezime = citac.GetString(3);
s.Godina = citac.GetInt32(4);
Polozio po = new Polozio();
po.BrPrijave = citac.GetInt32(5);
po.Student = s;
po.Predmet = p;
po.Ocena = citac.GetInt32(9);
lista.Add(po);
You can add columns to your DataGridView in your code like this
This will determine the column in your DataGridView:
dataGridView1.Columns.Add("ID", "ID");
dataGridView1.Columns.Add("Name", "Name");
And you can use LINQ ForEach to the list and add it to your DataGridView.
list.ForEach(m =>
{
dataGridView1.Rows.Add(m.ID, m.Name); //in your case, this is properties of Polozio class.
}
);
if you're not familiar with ForEach you can just use For loop in your list.
I have created a List called employees and I want to input all of the information from that List into a list box on the form.
I cannot believe I have forgotten this I have had a look around and I cannot find any concise information, I have a study book, but they use a TextBox instead of a ListBox and they only work with arrays and simple data types.
List<Employee> employees = new List<Employee>();
This is the list, it contains employees
Employee employee1 = new Employee(1111, "Name", "Skill Set");
I have created an instance of List
Then I add it to the list box on the form
lstFree.Items.Add(employees);
Yet it only appears as 'collection'
What am I doing wrong?
The Add method expects a single instance of your class. When you pass a collection to it, it calls ToString() and you end up seeing the full class name of the collection. Not what you want.
Instead, you could use a loop:
foreach (var emp in employees)
lstFree.Items.Add(emp);
Or just assign it to DataSource:
listBox1.DataSource = employees;
You'll also want to tell it which property to display to the user (and optionally, which property to use as the underlying value):
listBox1.DisplayMember = "Name";
listBox1.ValueMember = "EmpId"; // guessing what your class properties might be called
List<Employee> employees = new List<Employee>();
Employee employee1 = new Employee(1111, "Name", "Skill Set");
Employee employee2 = new Employee(2222, "Name", "Skill Set");
employees.Add(employee1);
employees.Add(employee2);
foreach(var empl in employees)
{
listBox1.Items.Add(empl.ToString());
}
In Employee class:
public override string ToString()
{
return ""; // return what you need
}
Consider using AddRange.
object[] arr = Enumerable.Range(1, 10000).Select(i=>(object)i).ToArray();
Compare time of this
// 1,29s
foreach (int i in arr)
{
listBox1.Items.Add(i);
}
to this
// 0,12s
listBox1.Items.AddRange(arr);
I´m having a problem, I retrieve all the Loans I have stored in my database like this:
list_loans = db.Loan.Where(x => x.State.id_state != 6).ToList();
db is the Object context.
Then, I assign that list as the DataSource for my DataGridView.
dgv_Loans.Datasource = list_loans;
With that info, I add some columns. Like for example, installments left to pay. I get that value by counting the result of a query.
The user can order the result using some options. Is easy to order the result from the fields that the entity have (using linq), but I dont know how to order the results using this new columns.
I read some posts here and tried this:
dgv_Loans.Sort(dgv_Loans.Columns["installments_left"], ListSortDirection.Ascending);
By doing this, I´m getting the following exception at runtime:
"DataGridView control must be bound to an IBindingList object to be sorted."
Is there anyway to use linq to orderby created columns in a DataGridViewColumn? Or how can I solve this error?
I know there are related posts, but after reading them, I can´t find a solution to this specific problem. Thats why I showed how I implemented to get some advice..
Rather than binding directly to the list retrieved from database, what I generally do is have a view class and have all the calculated properties in that class
public class LoanView : Loan {
public LoanView(Loan loan){
}
public int InsallmentsLeft { get { return ...; } }
}
and then bind the datasource to a list of this, this keeps sorting working.
Concerning about Sort datagridview by created columns using Entity Framework
I guess you need this Presenting the SortableBindingList<T>
Usage:
loanBindingSource.DataSource = new SortableBindingList<Loan>(list_loans.ToList());
dgv_Loans.Datasource = loanBindingSource;
int ID = Convert.ToInt32(cmbDepartments.SelectedValue);
var EmployeeList = from Employee in db.Employee
where Employee.DepartmentID == ID
select new
{
Employee.FirstName,
Employee.LastName
};
dataGridView1.DataSource = EmployeeList.ToList();
You could directly give the data source to dataGridView1.DataSource but you must write ToList() at the end of your query:
int ID = Convert.ToInt32(cmbDepartmanlar.SelectedValue);
dataGridView1.DataSource = (from Employee in db.Employee
where Employee.DepartmentID == ID
select new
{
Employee.FirstName,
Employee.LastName
}).ToList();
I have created a method to remove duplicates froma a DataView. I have not option to change the SQl query , so my only option is to modify the existing data retrieved from the Database in the DataView.
DataView data
Id, Name, Date
1, Paul, 12-05-2011
2, Mark, 12-05-2011
1, Paul, 12-05-2011
2, Mark, 12-05-2011
My method is:
private static void RemoveDuplicates(DataView source, string keyColumn)
{
DataRow[] dataRows = new DataRow[source.Table.Rows.Count];
source.Table.Rows.CopyTo(dataRows, 0);
var uniquePrimaryKeys = new List<Guid>(duplicateTable.Rows.Count);
foreach (DataRow row in duplicateTable.Rows)
{
if (uniquePrimaryKeys.Contains((Guid)row[keyColumn]))
source.Table.Rows.Remove(row);
else
uniquePrimaryKeys.Add((Guid)row[keyColumn]);
}
}
I wonder if there is a better method to achieve the same result but faster.
Actually, ADO.NET added a(n apparently not well known) feature that allows you to create a new table containing the distinct entries from an existing table. Here's how it works:
.....
.....
http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataset/thread/ed9c6a6a-a93e-4bf5-a892-d8471b84aa3b/
Could you use a linq group as an alternative? I couldn't say how much quicker it would be but I dare say it will be well optimised.
var result = from x in source.Table.AsEnumerable()
group x by new { id = x.Field<int>("ID"), Name = x.Field<string>("Name"), Date = x.Field<DateTime>("Date") }
into groupedResults
select groupedResults.Key;
i am currently working with SQL CE & WPF . in the middle of coding i struck with no idea of converting the dataset of a Database to my observablecollection which is binds to the UI Controllers like Listbox and listview.
plz guide me , if possible with code !!
Let's say your DataSet contains a Table named Person and that Person has columns Id, Name, and Age.
You first create a Person class to hold your Person data:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
Then you use LINQ to populate your ObservableCollection:
var people = new ObservableCollection<Person>(
dataset.Tables["Person"].AsEnumerable().Select(p => new Person
{
Id = p.Field<int>("Id"),
Name = p.Field<string>("Name"),
Age = p.Field<int>("Age")
}));
You will need to add the following assembly reference to your project in order to use the AsEnumerable<T>() and Field<T>() extension methods:
System.Data.DataSetExtensions (in System.Data.DataSetExtensions.dll)
Edit
In response to your comment, you would normally process each change you make to the data immediately rather than try to convert the whole ObservableCollection back to the DataSet. So, for example, if you add a new Person to your ObservableCollection, you would also want to add that Person to the DataSet.
Add a person:
var table = dataSet.Tables["Person"];
var row = table.NewRow();
row["Id"] = person.Id;
row["Name"] = person.Name;
row["Age"] = person.Age;
table.Rows.Add(row);
Delete a person:
var table = dataSet.Tables["Person"];
var row = table.AsEnumerable().Where(p => p.Id == person.Id);
row.Delete();
Update a person (say you want to change the age to 37):
var table = dataSet.Tables["Person"];
var row = table.AsEnumerable().Where(p => p.Id == person.Id);
var row["Age"] = 37;
You might also want to look into LINQ to SQL because it automates a lot of this stuff.