Load multiple lists in to one datatable - c#

Hi I have two lists one is parent list and other one is child list And I need to load the data contain in both list to single Datatable is there are way to do that
public class Country
{
string Name;
string Countrycode
list<Company> Companies=new list<Company>();
}
public class Company
{
string ComapnyName;
string Address1;
string Address2;
String Owner;
}
when creating table it must be like this
Name Countrycode ComapnyName Address1 Address2 Owner
USA 001 Apple Whereever null Jobbs
Japan 002 Sony Whereever null unknown

What's the problem? You can use a loop:
DataTable tblCountries = new DataTable();
// add all columns ...
foreach(Country c in allCountries)
{
if(c.Companies.Any())
{
foreach(var company in c.Companies)
{
var row = tblCountries.Rows.Add();
row.SetField("Name", c.Name);
row.SetField("Countrycode", c.Countrycode);
row.SetField("CompanyName", company.CompanyName);
// add the other company fields ...
}
}
else // add just the country and let the company cells be null
{
var row = tblCountries.Rows.Add();
row.SetField("Name", c.Name);
row.SetField("Countrycode", c.Countrycode);
}
}

You probably want to use microsofts example of how to create a copy to datable method show here MSDN
You can then do the following
Country.SelectMany(x => x.Companies
.Select(y => new {
x.Name,
x.CountryCode,
y.ComapnyName,
y.Address1,
y.Address2,
y.Owner
} )).CopyToDataTable();
PS copied the spelling of Comapny name not sure if you mean this!
Update to deal with Companies being null
If the companies property could be null:
Country.SelectMany(x => (x.Companies ?? Enumerable.Empty<Company>())
.Select(y => new {
x.Name,
x.CountryCode,
y.ComapnyName,
y.Address1,
y.Address2,
y.Owner
} )).CopyToDataTable();

Related

add two entry for every row - Linq C#

it is my query:
from customer in db.tblCustomers
select new
{
ID = customer.CustomerID,
Mobile = customer.Mobile1,
LastName = customer.Family
};
for every customer there is tow mobile phones, I need to add a new entry if the second mobile phone is not null. also I should change the LastName for second entry to something like "Second Mobile". How can I get two different entry from one customer using linq query?
Using the same generated type you can't have one with only one property of phone number and another with two. You can do:
from customer in db.tblCustomers
select new
{
ID = customer.CustomerID,
Mobile = customer.Mobile1,
SecondMobile = customer.Mobile2, // will be null if no second mobile exists
LastName = customer.Family
};
Otherwise what you can do is create a custom type Customer that will have a single phone number and a derived type ExtendedCustomer with two - and just instantiate the one or the other. Something along the psudo:
from customer in db.tblCustomers
select customer.Mobile2 != null ? new Customer(...) : new ExtendedCustomer(...);
If what you mean is having two different objects in the resulted collection then use union:
List<Customer> result = new List<Customer>();
foreach(var item in db.tblCustomers)
{
result.Add(new Customer(/*data for first mobile phone*/);
if(item.Mobile2 != null)
{
result.Add(new Customer(/*data for second mobile phone*/);
}
}
Could you please try this if it helps?
var customers = db.tblCustomers.SelectMany(x => x.GetMultipleRow()).ToList();
GetMultipleRow is an extension method as below.
public static class CustomerExtensions
{
public static IEnumerable<Customer> GetMultipleRow(this Customer cust)
{
yield return new Customer { CustomerID = cust.CustomerID, Mobile1 = cust.Mobile1, Family = cust.Family };
/* Data for first mobile*/
if (cust.Mobile2 != null)
yield return new Customer { CustomerID = cust.CustomerID, Mobile1 = cust.Mobile2, Family = cust.Family };
/* Data for second mobile*/
}
}

Filter null properties from list using Linq

I have a method that accepts a variable that has a list of properties connected to it. What I need to do is create a linq query that will flag the current variable coming in as missing an "address" and add it to a list.
public void Teachers(List<Teacher> teachers)
{
foreach (Name name in teachers)
{
int age = program.CalculateAge(name.BirthDate.Year);
Name address = FilterAddress(name);
// Output Teachers Name - First Name, Last Name
if (name.Type.Equals(Name.NameType.Teacher))
{
OutputToConsole(name.FirstName, name.LastName, age);
program.WriteAddress(name);
}
}
Console.WriteLine();
}
Above is the method that will add the current variable in foreach loop to the FilterAddress Method. Below is where the variable is being passed. This variable has a List property named "Address" that is connected to it. This address can be null. I need to select each name with an address of null and add it to a list. But as you guessed, my LINQ code below doesn't work and just breaks.
public Name FilterAddress(Name name)
{
var NullItems = name.Select(x => x.Addresses).OfType<Name>();
return NullItems;
}
public Name[] FilterAddress(Name name)
{
return name.Where(x => string.IsNullOrEmpty(x.Addresses))
.Select(x => x.Name)
.ToArray();
}
Only need to add the "if null" check in the query to return if Adresses is null.
var NullItems = name.Where(x => x.Addresses == null);

Load data from txt file to comboBox

Hi i have this structure of txt file:
Lukas 1
Zdenek 3
Martin 2
Kate 1
And i need load this data...the name i need load to comboBox...and when i choose from ComboBox for example Lukas, i need to save Name Lukas to variable Name and number 1 to variable Number...
It is possible?
I have this code now...
using (StreamReader reader = new StreamReader(#"C:\Us...nka\example.txt"))
{
string data = "";
data = reader.ReadToEnd().Trim();
}
But i need read separately Name and separately Number...Have you any ideas? Thanks..
You can use File.ReadLines and String.Split:
var lines = File.ReadLines(#"C:\Us...nka\example.txt");
var data = lines.Select(l => l.Split());
I would use a class to store both properties:
public class Person
{
public int PersonID { get; set; }
public string PersonName { get; set; }
}
Now you can load the persons in a loop or with LINQ:
List<Person> allPersons = data
.Where(arr => arr.Length >= 2 && arr[1].Trim().All(Char.IsDigit))
.Select(arr => new Person
{
PersonName = arr[0].Trim(),
PersonID = int.Parse(arr[1].Trim())
})
.ToList();
Edit:
Yes thanks...but i cant load PersonsName to combobox
You can use a BindingSource for the ComboBox. Then set the DisplayMember and ValueMember properties accordingly:
var bindingSourcePersons = new BindingSource();
bindingSourcePersons.DataSource = allPersons;
personComboBox.DataSource = bindingSourcePersons.DataSource;
personComboBox.ValueMember = "PersonID";
personComboBox.DisplayMember = "PersonName";
First create a class like this:
public class Person {
public string Name {get;set;}
public int Number {get;set;}
}
then you can use Linq to convert the string you read like this:
var people = data
.Split(new {'\r','\n'}, StringSplitOptions.RemoveEmptyEntries)
.Select(d => new Person { Name = d.Split(' ')[0], Value = int.Parse(d.Split(' ')[1])})
.ToList();
Or better you could read your data line by line, like this:
var people = from l in File.ReadLines(#"C:\Us...nka\example.txt")
let parts = l.Split(' ')
select new Person {
Name = parts[0].Trim(),
Value = int.Parse(parts[1].Trim())
};
here is a pseudo:
while the reader is not EndOfStream
read current line
split the line that was just read into a string[] array, the separator being a space
first item in the array would be the name and the second item in the array would be the number.
then you add the item in the combo box. The combobox has an Items collection and an add method, which just takes a System.Object.
http://msdn.microsoft.com/en-us/library/aa983551(v=vs.71).aspx

Cannot implicitly convert type '.List<AnonymousType#1>' to '.List<WebApplication2.Customer>'

In the following code that returns a list:
public List<Customer> GeAllCust()
{
var results = db.Customers
.Select(x => new { x.CustName, x.CustEmail, x.CustAddress, x.CustContactNo })
.ToList()
return results;
}
I get an error reporting that C# can't convert the list:
Error: Cannot implicitly convert type System.Collections.Generic.List<AnonymousType#1> to System.Collections.Generic.List<WebApplication2.Customer>
Why is that?
Here's a screenshot showing some additional information that Visual Studio provides in a tooltip for the error:
Is it right way to return some columns instead of whole table....?
public object GeAllCust()
{
var results = db.Customers.Select(x => new { x.CustName, x.CustEmail, x.CustAddress, x.CustContactNo }).ToList();
return results;
}
When you look the code:
x => new { ... }
This creates a new anonymous type. If you don't need to pull back only a particular set of columns, you can just do the following:
return db.Customers.ToList();
This assumes that Customers is an IEnumerable<Customer>, which should match up with what you are trying to return.
Edit
You have noted that you only want to return a certain subset of columns. If you want any sort of compiler help when coding this, you need to make a custom class to hold the values:
public class CustomerMinInfo
{
public string Name { get; set; }
public string Email { get; set; }
public string Address { get; set; }
public int? ContactNumber { get; set; }
}
Then change your function to the following:
public List<CustomerMinInfo> GetAllCust()
{
var results = db.Customers.Select(x => new CustomerMinInfo()
{
Name = x.CustName,
Email = x.Email,
Address = x.Address,
ContactNumber = x.CustContactNo
})
.ToList();
return results;
}
This will work, however, you will lose all relationship to the database context. This means if you update the returned values, it will not stick it back into the database.
Also, just to repeat my comment, returning more columns (with the exception of byte arrays) does not necessarily mean longer execution time. Returning a lot of rows means more execution time. Your function is returning every single customer in the database, which when your system grows, will start to hang your program, even with the reduced amount of columns.
You are selecting to an anonymous type, which is not a Customer.
If you want to do (sort of) this, you can write it like this:
return db.Customers.Select(x => new Customer { Name = x.CustName, Email = x.CustEmail, Address = x.CustAddress, ContactNo = x.ContactNo }).ToList();
This assumes the properties on your Customer object are what I called them.
** EDIT ** Per your comment,
If you want to return a subset of the table, you can do one of two things:
Return the translated form of Customer as I specified above, or:
Create a new class for your business layer that only has only those four fields, and change your method to return a List<ShrunkenCustomer> (assuming ShunkenCustomer is the name that you choose for your new class.)
GetAllCust() is supposed to return a List of Customer, Select New will create a list of Anonymous Types, you need to return a list of Customer from your query.
try:
var results = db.Customers.Select( new Customer{CustName = x.CustName}).ToList(); //include other fields
I guess Customer is a class you have defined yourself?
The my suggestion would be to do something like the following:
var results = db.Customers.Select(x => new Customer(x.Custname, x.CustEmail, x.CustAddress, x.CustContactNo)).ToList();
The reason is that you are trying to return a list of Customer but the results from your link is an anonymous class containing those four values.
This would of course require that you have a constructor that takes those four values.
Basically whatever u got in var type, loop on that and store it in list<> object then loop and achieve ur target.Here I m posting code for Master details.
List obj = new List();
var orderlist = (from a in db.Order_Master
join b in db.UserAccounts on a.User_Id equals b.Id into abc
from b in abc.DefaultIfEmpty()
select new
{
Order_Id = a.Order_Id,
User_Name = b.FirstName,
Order_Date = a.Order_Date,
Tot_Qty = a.Tot_Qty,
Tot_Price = a.Tot_Price,
Order_Status = a.Order_Status,
Payment_Mode = a.Payment_Mode,
Address_Id = a.Address_Id
});
List<MasterOrder> ob = new List<MasterOrder>();
foreach (var item in orderlist)
{
MasterOrder clr = new MasterOrder();
clr.Order_Id = item.Order_Id;
clr.User_Name = item.User_Name;
clr.Order_Date = item.Order_Date;
clr.Tot_Qty = item.Tot_Qty;
clr.Tot_Price = item.Tot_Price;
clr.Order_Status = item.Order_Status;
clr.Payment_Mode = item.Payment_Mode;
clr.Address_Id = item.Address_Id;
ob.Add(clr);
}
using(ecom_storeEntities en=new ecom_storeEntities())
{
var Masterlist = en.Order_Master.OrderByDescending(a => a.Order_Id).ToList();
foreach (var i in ob)
{
var Child = en.Order_Child.Where(a => a.Order_Id==i.Order_Id).ToList();
obj.Add(new OrderMasterChild
{
Master = i,
Childs = Child
});
}
}

Add null values to a datagridview

In my C# application I have a datagridview with 'person' data in it that means the datasource of this datagrisview is set with an IList of the class person.
My person model consists of the following fields (just the model, not the datagridview):
string foreName
string surname
int devisionId
int someOtherId
Organisation orga
Organisation is another model which is mapped as one-to-many with NHibernate. Among others organisation consists of the string:
string orgaName
Now comes the tricky part (for me)....
In my datagridview I dont want to have all fields of person, I just want to have the following:
foreName
surname
orga.orgaName
Getting the first twoe fields is easy:
dataGridView.DataSource = listOfPersons.Select(x => new { ForeName = x.ForeName, SurName = x.Surname}).ToList();
This works fine so far but now I also want to have the name of the organisation within my datagridview so I tried this:
dataGridView.DataSource = listOfPersons.Select(x => new { ForeName = x.ForeName, SurName = x.Surname, OrganisationName = x.Organisation.organName}).ToList();
This would also work fine if every person has an organisation, but thats not the fact. Some persons do not have an organisation so 'Organisation' is null and trying to grab Organisation.organName ends with a nullpointerexeption.
The question now is:
How can I write my select-statement for the datagridview-datasource so that the organisation name is shown when Organisation is not null, otherwisesomething else is printed to the datagridview (for example: no organisation available)
dataGridView.DataSource = listOfPersons.Select(x => new { ForeName = x.ForeName, SurName = x.Surname, OrganisationName = x.Organisation == null ? "None" : x.Organisation.organName}).ToList();
Try this :
dataGridView.DataSource = listOfPersons.Select(x => new { ForeName = x.ForeName, SurName = x.Surname, OrganisationName = x.Organisation != null ? x.Organisation.organName : "No organisation available"}).ToList();

Categories

Resources