I've three tables:
Car
Parts
SubParts
Now I want to get data from all the three tables, which is easy by performing inner join I can easily get that. My SQL query is
Select C.Id AS CarId,C.Name AS CarName
, P.Id AS PartsId,P.Name AS PartsName
, SP.Id AS SubPartsId,SP.Name AS SubPartsName
from Car C
INNER JOIN Parts P on C.Id=P.CarId
INNER JOIN SubParts SP on P.Id=SP.PartsId
In C# I've same entities with same properties as that of table columns and the same name as that of the table, now I want to populate data from a single query in three different entities without iterating each record returned from SQL query. Is there any that can be done in using ADO.NET or Enterprise Library(more preferable).
Use the join from LINQ.
var innerJoinQuery =
from car in cars
join part in parts on car.Id equals part.CarId
join subPart in subParts on part.Id equals subPart.PartId
select new {
CarId = car.Id,
CarName = car.Name,
PartsId = part.Id,
PartsName = part.Name,
SubPartsId = subPart.Id,
SubPartsName = subPart.Name
};
Related
I have two related tables. Then I use LINQ to query Data.
this is my code
var items = await (from a in queryable
join b in _context.TUserGrant on a.UserNo equals b.UserNo
join c in _context.TProviderInfo on a.ProviderNo equals c.ProviderNo
orderby a.BillNo
select new
{
a.BillNo,
a.NotificeBillNo,
makeName = b.UserName,
a.MakeDate,
a.ProviderNo,
c.ProviderName,
a.CheckTime,
a.CheckAddress,
a.CheckName,
a.StatusTitle,
}).ToListAsync();
My problem is that I need all the columns of the first table, which is all the values of A.
I also need some columns from table B.
I wonder if there is an easy way to get these columns.
Instead of setting them one by one in the SELECT method.
You can try this
var items = await (from a in queryable
join b in _context.TUserGrant on a.UserNo equals b.UserNo
join c in _context.TProviderInfo on a.ProviderNo equals c.ProviderNo
orderby a.BillNo
select new
{
tabA = a,
makeName = b.UserName
}).ToListAsync();
I could not get the linq query to retrieve information from different tables and return it as a list.
For example customer id >> 5, I can write the code in mssql:
SELECT *
FROM crm_customer_authorized AS AUTHORIZEDs
INNER JOIN crm_authorized_describing AS authorized ON AUTHORIZEDs.authorizedId=authorized.authorizedId
INNER JOIN crm_customer_describing AS customer ON customer.customerid = AUTHORIZEDs.customerid
INNER JOIN crm_address_describing AS adress ON adress.customerid = customer.customerid
INNER JOIN crm_customer_sector AS SEKTORS ON sektors.customerid = customer.customerid
INNER JOIN crm_sector_describing AS sektor ON sektor.sektorid = sektors.sektorid
INNER JOIN crm_customer_departman AS departments ON departments.customerid = customer.customerid
INNER JOIN crm_branch_describing AS department ON department.departmentId= departments.departmentsId
INNER JOIN address_codes_province AS province ON addresss.provinceid = province.addresscodeid
INNER JOIN address_codes_provincece AS provincece ON addresss.provinceceid= provincece.section_code
LEFT JOIN crm_position_describing AS POSITION ON authorized .positionId = position.positionid
output:
Result
How can I write this query with linq?
A customer has more than one address, responsible person.
A responsible person, a customer may be in the same sector, but the authorities are different.
I do not know the code of how to list more than one different information of a customer
I got the customerIds from the customer table
var customerIds = from cus in db.customerDescribing
select new { cus.customerId };
I was then synchronize the customer s in the address table
foreach (var item in customerIds )
{
var linq2 = (from address in db.addressDescribing.Where(x => x.customerId== item.customerId)
select new
{
Address = address.content,
CustomerId= address.customerId
}).ToArray();
}
but I do not know how to keep synchronizing with other tables
Assuming you are not using LINQ to Entities but just LINQ to SQL,
For translating SQL to LINQ,
Translate subselects as separate variables
Translate each clause in LINQ clause order, leaving monadic operators (DISTINCT, TOP, etc) as functions applied to the whole LINQ query.
Use table aliases as range variables. Use column aliases as anonymous type field names.
Use anonymous types (new { }) for multiple columns
Left Join is simulated by using a join variable and doing another from from the join variable followed by .DefaultIfEmpty().
Replace COALESCE with the conditional operator and a null test.
SELECT * must be replaced with select range variable or for joins, an anonymous object containing all the range variables.
SELECT flds must be replaced with select new { ... } creating an anonymous object with all the desired fields or expressions.
Following this process on your query I get:
var ans = from AUTHORIZEDs in db.customerAuthorized
join authorized in db.authorizedDescribing on AUTHORIZEDs.authorizedId equals authorized.authorizeId
join customer in db.customerDescribing on AUTHORIZEDs.customerid equals customer.customerid
join adress in db.addressDescribing on customer.customerid equals adress.customerid
join SEKTORS in db.customerSector on customer.customerid equals SEKTORS.customerid
join sektor in db.sectorDescribing on SEKTORS.sektorid equals sektor.sektorid
join departments in db.customerDepartman on customer.customerid equals departments.customerid
join department in db.branchDescribing on departments.departmentsId equals department.departmentId
join province in db.addressCodesDrovince on adress.provinceid equals province.addresscodeid
join provincece in db.addressCodesProvincece on adress.provinceceid equals provincece.section_code
join POSITION in db.positionDescribing on authorized.positionId equals POSITION.positionid into POSITIONj
from POSITION in POSITIONj.DefaultIfEmpty()
select new { AUTHORIZEDs, authorized, customer, adress, SEKTORS, sektor, departments, department, province, provincece, POSITION };
I have the following tables in my database:
SageAccount
ID (bigint)
LegacyID (nvarchar)
Customer (bit)
Consignments
ID (bigint)
Customer (nvarchar)
What I want to do is have a navigation property/association in my Linq to Sql dbml from Consignment to SageAccount. The difficulty with this is that not only do we need to match SageAccount.LegacyID => Consignments.Customer but we also need to only join to sage accounts where SageAccount.Customer is TRUE. So on the Consignments end, it isn't joining onto a field but instead a static value.
Is this possible in Linq to Sql? Note this database doesn't (and unfortunately can't) have any foreign keys setup in the database.
Yes it is possible. linq have join method. You can use it ike this in your situation:
var res = from sageAccount in _context.SageAccount
join consignments in _context.Consignments
on
new
{
LegacyID = sageAccount.LegacyID,
Customer = sageAccount.Customer
}
equals
new
{
LegacyID = consignments.ID,
Customer = true
}
select new { SageAccountID = sageAccount.ID };
Note that Property name, Type and order in the anonymous objects that you're joining on must match.
You can't use OR and AND in joins - use just equals one object to other.
This will have a this kind of result in your SQL:
SELECT [t0].[ID] AS [SageAccountID]
FROM [dbo].[SageAccount] AS [t0]
INNER JOIN [dbo].[Consignments] AS [t1] ON (([t0].[LegacyID]) = [t1].[ID])
AND ([t0].[Customer] = 1)
How do I update two tables at the same time using Linq-to-SQL?
var z = from a in db.Products
join b in db.ProductSubcategories on
a.ProductSubcategoryID equals b.ProductSubcategoryID
join d in db.ProductCategories on
b.ProductCategoryID equals d.ProductCategoryID
select new { ProductName = a.Name, ProductCategory = d.Name,
ProductSubCategory = b.Name, Cost = a.StandardCost,
discontinuedDate = a.DiscontinuedDate,
ProductId=a.ProductID };
You have to update individual records from each table and then execute db.SubmitChanges();
In your query the output is an anonymous type, not a table type connected to the db context.
If you think in terms of SQL, linq2sql works pretty much the same. You can select a record set with a join, but you cannot update directly on this. You need to break it up and modify entries directly on Products, ProductCategories and ProductSubCategories, which equals the tables in your database.
If you want to modify a Product in Products then you have to modify the properties of that type, and not the anonymous type (joined type).
I am not sure if this can be done, but here's the scenario.
I want to turn this sql into linq:
SELECT * FROM Department d
INNER JOIN Employee e ON e.DepartmentID = d.DepartmentID
Department - Employee is 1 to many relationship.
I have created a custom object that I would like to populate the result into.
public class DepartmentSummary
{
public Department Department { get; set; }
public List<Employee> Employees {get; set;}
}
The Linq I came up with is
var result = from d in dba.Department
join e in dba.Employee d.DepartmentID equals e.DepartmentID into j1
select new DepartmentSummary
{
Department = d,
Employees = j1.ToList()
};
I tried it out and it's not working. Can anyone shed some light for me please? I would like to perform an inner join between Department and Employee. For each Department in the resultset, I would like to create one DepartmentSummary object which holds that department and a list of employees belonging to that department.
Does Linq provides an ad hoc solution for this or must I iterates through the result set and create a list of DepartmentSummary manually?
Thanks,
EDIT:
Looks like this works for me
var result = from d in dba.Department
join e in dba.Employee d.DepartmentID equals e.DepartmentID into j1
where j1.Count() > 0
select new DepartmentSummary
{
Department = d,
Employees = j1.ToList()
};
The thing is that you're not really taking one SQL and trying to create a Linq-query out of it.
If you were, you'd notice that your SQL query does not really produce one row per department, but it will repeat the department information for each employee in that department.
Now, an initial naive look would suggest you use a group-by clause, since that would allow you to split the data into individual groupings for each department, but groupings in SQL does not really give you a key+all-matching-rows type of result, rather it allows you to do aggregate calculations, like "for each department, how many employees do I have".
So, in order to do what you want, you need to basically do a normal join, which will give you each employee, coupled with the appropriate department information (ie. each employee will be linked to his/her department), and then you need to construct the rest of the data structure yourself.
Now, having said that, if you have the proper relationships set in your data context related classes, each department should already have some kind of property that contains all employees in that department, so perhaps the simple query is just "give me all departments", and then you can, for each department, retrieve the employees?
Of course, doing that would likely execute one SQL for each department, but in this case, you're back to "give me all employees with their department information" and you have to build code to handle the rest.
LINQ to SQL doesn't understand your ToList() call, but you might be able to select the sequence of joined elements and then use LINQ to Objects (via AsEnumerable()) to map to your DepartmentSummary object:
var qResult = from d in dba.Department
join e in dba.Employee d.DepartmentID equals e.DepartmentID into j1
select new
{
Department = d,
Employees = j1
};
var result = from d in qResult.AsEnumerable()
select new DepartmentSummary()
{
Department = d.Department,
Employees = e.Employees.ToList()
};
Sounds like you're looking to get around lazy loading?
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Department>(d => d.Employees);
using (var dba = new MyDataContext())
{
dba.LoadOptions = dlo;
var result = from d in dba.Department
select d;
}
Now, if you don't have a relationship defined between Department and Employees (the Linq2Sql designer will do this for you if you have database relationships setup) then you should look into doing that. It makes it all dramatically easier. In fact, you don't even need your campaign summary.
This problem is due to the nature of the query. When you join Department to Employee, you'll get back one record for every Employee. This means that your ToList() statement is expecting multiple employees per department, but due to the join, always getting one.
Change your query to
var result =
from d in dba.Department
select new tCampaignSummary
{
Department = d,
Employees = dba.Employee.Where(e => e.DepartmentID ==
d.DepartmentID).ToList()
};
I've tested this and it works.
What it does differently is selects only one record per Department (not per employee) then it gets the zero to many corresponding employees for each dept and converts them to a list.
Good luck!
EDIT
As requested, here is the generated SQL:
SELECT [t0].*, [t1].*
(
SELECT COUNT(*)
FROM [dbo].[Employee] AS [t2]
WHERE [t2].[DepartmentID] = [t0].[DepartmentID]
) AS [value]
FROM [dbo].[Department] AS [t0]
LEFT OUTER JOIN [dbo].[Employee] AS [t1]
ON [t1].[DepartmentID] = [t0].[DepartmentID]
ORDER BY [t0].[DepartmentID], [t1].[IndexID]
The only modification is that LINQ will not do [t0].*, instead it will enumerate each field. Since I had to guess at the fields, I left them out to make the SQL clearer.