getting two column values from same table depending on the condition - c#

I have two tables:
table product1 with columns:
product_id
prodcut_name
category_id
another table categories
category_id
category_name
category_description
I am populating product details using DataGridView and it's working fine.
I am trying to get the two column values from same table depending on the same condition that I have got the code below:
string desc = Convert.ToString(selectedRow.Cells["productdescr"].Value);
string productname = Convert.ToString(selectedRow.Cells["productnam"].Value);
string productprices = Convert.ToString(selectedRow.Cells["productprice"].Value);
int productids = Convert.ToInt32(selectedRow.Cells["productid"].Value);
condition 1:
int categoryids = (from cats in tsg.product1
where cats.product_Name.Equals(productname)
select cats.category_Id).SingleOrDefault();
condition 2:
var catogynames = (from categorytypes in tsg.categories
where categorytypes.category_Id.Equals(categoryids)
select categorytypes.category_Name
).SingleOrDefault();
condition 3:
var categoprydecription = (from categorytable in tsg.categories
where categorytable.category_Id.Equals(categoryids)
select categorytable.category_Description
).SingleOrDefault();
I want to get the categorytypes.category_description also along with this categorytypes.category_Name from the condition 2, is it possible to combine the two conditions? (condition 2 and condition 3)

I think you can do this in this fashion
(from categorytable in tsg.categories
where categorytable.category_Id == categoryids
select new {Name=categorytable.category_Name,
Description=categorytable.category_Description}).SingleOrDefault();
This will be an anonymous class holding both name and description of the categories you want.

Related

Select and group data from 2 datatables with linq and display the result on datagridview

I have 2 DataTables which contain data about employees and orders. I need to get the count of the orders associated with each employee as well as the employee's ID and name.
This SQL shows the data in the format I want it:
select e.EmployeeID as ID,
(e.LName+' '+e.FName+' '+e.MName) as 'Full name',
COUNT(e.EmployeeID) as 'Sales number'
from Employees as e
join Orders as o on e.EmployeeID=o.EmployeeID
group by e.EmployeeID, e.FName, e.LName, e.MName
How can I use LINQ to get the data and display the results in a dataGridView?
This is my code so far:
private void Form1_Load(object sender, EventArgs e)
{
var empSales = from emp in Shop.ShopDB.Tables["Employees"].AsEnumerable()
join order in Shop.ShopDB.Tables["Orders"].AsEnumerable()
on emp.Field<int>("EmployeeID") equals order.Field<int>("EmployeeID")
group emp by emp.Field<int>("EmployeeID");
IEnumerable<DataRow> DataRows = empSales.SelectMany(group => group);
List<object[]> list= DataRows.Select(dr => dr.ItemArray).ToList();
//trying to get the final object but group's key is not available
//because these datarows don't have that field
var empss = DataRows.Select(d => new
{
ID = d.Field<int>("EmployeeID"),
Фамилия = d.Field<int>("Lname"),
Имя = d.Field<int>("Fname"),
Отчество = d.Field<int>("Mname")
});
EmployeesSalesGridView.DataSource = list;
}
Here is a script with some sample data:
create table Orders (OrderID int, CustomerNo int, OrderDate datetime, EmployeeID int)
insert into Orders select 1, 1, '2009-12-28', 2
insert into Orders select 2, 3, '2010-09-01', 4
insert into Orders select 3, 4, '2010-09-18', 4
insert into Orders select 4, 1, '2010-12-10', 2
create table Employee (EmployeeID int, FName varchar(20), LName varchar(20), MName varchar(20))
insert into Employee select 1, 'Alpha', 'Bravo', 'Charlie'
insert into Employee select 2, 'Delta', 'Echo', 'Foxtrot'
insert into Employee select 3, 'Golf', 'Hotel', 'India'
insert into Employee select 4, 'Jacob', 'Kilo', 'Lima'
If I understand the problem correctly, then you want the result to contain the following columns: EmployeeID, FullName, and SalesNumber and to match the result from the SQL query.
In your code you have the comment:
//trying to get the final object but group's key is not available
//because these datarows don't have that field
You almost have the correct Linq query. The problem is that you're flattening the group when you use SelectMany, that's why you can no longer access the group key. There's no need to use SelectMany here.
Select the desired data into an anonymous object, then use it as the DataSource for the GridView:
var empSales = from emp in Shop.ShopDB.Tables["Employees"].AsEnumerable()
join order in Shop.ShopDB.Tables["Orders"].AsEnumerable()
on emp.Field<int>("EmployeeID") equals order.Field<int>("EmployeeID")
group emp by emp.Field<int>("EmployeeID") into g
select new
{
EmployeeID = g.Key,
FullName = g.First().Field<string>("FName") + " " +
g.First().Field<string>("MName") + " " +
g.First().Field<string>("LName"),
SalesNumber = g.Count()
};
EmployeesSalesGridView.DataSource = empSales.ToList();
Which produces the same result as the SQL query for your sample data:

Combining two tables and writing a query from them into a list

I have 2 tables in the database - Customer and Product.
I perform the selection by skipping the first row in the table and then getting the top two rows.
The result I need to get in the List cusPod .
List<Customer> customers = db.Database.SqlQuery<Customer>("SELECT * FROM Customers ORDER BY CustomerId OFFSET 1 ROWS FETCH NEXT 2 ROWS ONLY").ToList();
List<Product> products = db.Database.SqlQuery<Product>("SELECT * FROM Products ORDER BY ProductId OFFSET 1 ROWS FETCH NEXT 2 ROWS ONLY").ToList();
var listSas = from p in products
join c in customers on p.ProductId equals c.CustomerId
select new { ProductId = p.ProductId, ProductName = p.ProductName, DateStart = p.DateStart, DateEnd = p.DateEnd, DateRegister = p.DateRegister, PriceCustomer = p.PriceCustomer, CheckPay = p.CheckPay, CustomerId = p.CustomerId, FIO = c.FIO, Email = c.Email, PhoneNumber = c.PhoneNumber };
SidebarController.cusPod = listSas.ToList();
how do I do this right?
From the code it seems that you are using entity framework as your ORM, therefore, you can easily use the Skip and Take methods of EF that are great features instead of writing hard coded sql. for example:
db.Customers.OrderBy(c => c.CustomerId).Skip(1).Take(2);
The rest of your logic seems fine.

How to get two table value using Linq

I have two table one is Administrator table and another is Teacher table .
I want to display these both tables values in single Gridview .
I have make id as a primary key in Administrator table and make this tech_id as foreign key in Teacher table .
Now how to get these table values together in single gridview as shown in pic
Now please any body help me how to get these two value together using Linq .
I have try but I can't make any more
private void loadgri()
{
StudentDatabaseEntities empl = new StudentDatabaseEntities();
var query=from g in empl.Teachers
join m in empl.Administrators on g.id equals m.id
where m.username=="cs"
select new{
Name = g.username,
};
}
You don't need a join if you have already a navigation-property:
var query= from t in empl.Teachers
where t.Administrator.username == "cs"
select new { Teacher = t.username, Administrator = t.Administrator.username };
This is just an example, but you see that you can access all properties of both entities.
Don’t use Linq’s Join. Navigate!
To show all the teachers and their administrator, you don't have to use "join", you could just use the navigation property:
var query = from g in empl.Teachers
where g.Administrator.username=="cs"
select new {
Teacher_Id = g.Id,
Teacher_Name = g.username,
Administrator_Id = g.Id,
Administrator_Name = g.Administrator.username,
//etc...
};

taking more than one cells into one cell

I am using a linq query to obtain a table of customers with their total money amount for each monetary unit exist in my database(this one is ok.)
when show the result of my query with Microsoft Report Viewer the result is like Table 1 but what i want is Table 2, only the customer name like "A" and a cell with all the monetory unit records > 0.
Is there any way you can suggest?
This is my code which produces Table 1:
var query = from kur in kurToplamlist
join cariBilg in db.TBLP1CARIs
on kur.CariIdGetSet equals cariBilg.ID
select new
{
cariBilg.ID,//customerid
EUROBAKIYE = cariBilg.HESAPADI,
cariBilg.K_FIRMAADI,//other column names
cariBilg.K_YETKILIADI,//other column names
cariBilg.K_FIRMATELEFON,//other column names
cariBilg.K_YETKILITELEFON,//other column names
AUDBAKIYE = cariBilg.B_CEPTELEFON,//other column names
MonetaryUnit = String.Concat(kur.KurToplamMiktarGetSet.ToString(), kur.DovizTuruGetSet.ToString()),//concatenates "100" and "TL/USD etc."
};
What i want is to obtain Table 2 in the image
Thank you in advance.
Table image
var query = from kur in kurToplamlist
where kur.KurToplamMiktarGetSet > 0
join cariBilg in db.TBLP1CARIs
on kur.CariIdGetSet equals cariBilg.ID
select new
{
cariBilg.ID,
EUROBAKIYE = cariBilg.HESAPADI,
cariBilg.K_FIRMAADI,
cariBilg.K_YETKILIADI,
cariBilg.K_FIRMATELEFON,
cariBilg.K_YETKILITELEFON,
AUDBAKIYE = cariBilg.B_CEPTELEFON,
TLBAKIYE = String.Concat(kur.KurToplamMiktarGetSet.ToString(), kur.DovizTuruGetSet.ToString()),
};
var dfg = from qre in query
select qre.TLBAKIYE;
var aq = (from qw in query
select new {
qw.ID,
EUROBAKIYE = qw.EUROBAKIYE,
qw.K_FIRMAADI,
qw.K_YETKILIADI,
qw.K_FIRMATELEFON,
qw.K_YETKILITELEFON,
AUDBAKIYE = qw.AUDBAKIYE,
TLBAKIYE = String.Join(",", (from qre in query
where qre.ID == qw.ID
select qre.TLBAKIYE).Distinct())
}).Distinct();
return aq;
This is my answer.

How to get data from two SQL tables into .net

Previously, I asked a question about getting data from two tables where I take one row in a table and join it with several rows in another table. Here's the link to that discussion: SQL Select data from two tables (one row -> multiple rows)
Here is my SQL code:
SELECT
customer.fName, customer.lName, phone.phoneNumber
FROM
Customers customer
INNER JOIN phoneNumbers phone ON
customer.customerId = phone.customerId
What I would like to know now is: what is the best way to get this data organized in .net?
Let's suppose I have a C# class as following:
public class CustomerDetails
{
int customerId;
string fname;
string lName;
List<string> phoneNumbers;
}
For the sake of discussion, let's suppose that the above SQL query returns the following result:
fname, lname, phoneNumber
"John", "Smith", "111-111"
"Jane", "Doe", "222-1111"
"Jane", "Doe", "222-2222"
At a glance, I see that I have two customers; one has one phone number and the other has two phone numbers. How can I write code to efficiently parse this in C#?
One option is to use LINQ to create a instance of the CustomerDetails class.
Let me know if you would like an example.
Example 1:
List<CustomerDetails> customers = db.Customers.Select(c => new CustomerDetails(){
customerId = c.customerID,
fname = c.fName,
lName = c.lName,
phoneNumbers = (from p in db.PhoneNumbers where p.customerID == c.customerID select p.phoneNumber1).ToList<String>()});
Example 2:
List<CustomerDetails> custs = (from c in db.Customers
select new CustomerDetails()
{
customerId = c.customerID,
fname = c.fName,
lName = c.lName,
phoneNumbers = (from p in db.PhoneNumbers where p.customerID == c.customerID select p.phoneNumber1).ToList<String>()
}).ToList<CustomerDetails>();
I understand that you are looking for ORM object-relational mapping. In .NET I can recommend IBatis.net or LINQ.
Solution 1:
I assume that the records are sorted by name in the SQL query's results and that you also select the customerID. Appending "ORDER BY customer.fName, customer.lName" to your original query will do the trick.
I'll assume that you get your result in a DataReader, so you can do the following:
// Lets start by declaring a collection for our records
List<CustomerDetails> myRecords = new List<CustomerDetails>();
// Iterate all records from the results and fill our collection
while (yourReader.Read())
{
int customerID = int.Parse(yourReader["customerID"]);
int nrRecords = myRecords.Count;
if (nrRecords > 0 && myRecords[nrRecords - 1].customerId == customerID)
{
myRecords[nrRecords - 1].phoneNumbers.Add(yourReader["phoneNumber"]);
}
else
{
CustomerDetails newCustomerDetails = new CustomerDetails();
newCustomerDetails.customerId = customerID;
newCustomerDetails.fName = yourReader["fName"];
newCustomerDetails.lName = yourReader["lName"];
List<string> phoneNumberList = new List<string>();
phoneNumberList.Add(yourReader["phoneNumber"]);
newCustomerDetails.phoneNumbers = phoneNumberList;
myRecords.Add(newCustomerDetails);
}
}
P.S. If ordering the list is not an option, then you can't just check the latest added records customerid - instead you'll need to iterate through the myRecords list and search for the existance of it. This can be done in many ways including with myRecords.Contains() or with a foreach.
Solution 2:
Do the telephone number grouping directly from SQL. Create a function for selecting a comma separated string with all the telephone numbers of a particular customer:
CREATE FUNCTION [dbo].[GetCommaSeparatedPhoneNumbers]
(
#customerID int
)
RETURNS varchar(max)
AS
BEGIN
declare #output varchar(max)
select #output = COALESCE(#output + ', ', '') + phoneNumbers
from phoneNumbers
where customerId = #customerID
return #output
END
GO
Then you can nicely select the list of all customer you want:
SELECT customerId, dbo.GetCommaSeparatedPhoneNumbers(customerId)
FROM Customers
GROUP BY customerId
This will return:
"John", "Smith", "111-111"
"Jane", "Doe", "222-1111,222-2222"
Now it's all a question of parsing the results with a foreach or while loop, but no checking for existance is needed. Just split the string at ',' and insert the values into the List. If there is a chance, that there will be no phone numbers for some customers, then you can filter that field for null.
PS. Will not work if there is a comma as pointed out by BQ in his comment.
Iterate over the result, for each row check if it is in your list of costumers, if not, add a new one, if yes, add the phone number to the existing one.
Of course, you shouldn't parse the string use appropiate classes to access the database, like ado.net.

Categories