How to use if statement when using linq to sql join? - asp.net

I'm using linq to sql on my asp.net project and i locked in somewhere. I select data amoung relationship tables and I use following codes. But the question is if supplierID is different than 0 there is no problem for query. Query is working as successful. But if supplierId is 0 query returns nothing. I want to use if statement when i join tables but how ?
My Codes,
EnvanterDataContext dc = new EnvanterDataContext();
var invent = from equipment in dc.tEquipments
where equipment.EquipmentID == id
orderby equipment.EquipmentID descending
join supplier in dc.tSuppliers on equipment.SupplierID equals supplier.SupplierID
join model in dc.tModels on equipment.ModelID equals model.ModelID
join equipmentType in dc.tEquipmentTypes on equipment.TypeID equals equipmentType.EquipmentTypeID
join equipmentStatus in dc.tEquipmentStatus on equipment.StatusID equals equipmentStatus.EquipmentStatusID
select equipment;
I want to use
EnvanterDataContext dc = new EnvanterDataContext();
var invent = from equipment in dc.tEquipments
where equipment.EquipmentID == id
orderby equipment.EquipmentID descending
if(equipment.SupplierID != 0)
join supplier in dc.tSuppliers on equipment.SupplierID equals supplier.SupplierID
join model in dc.tModels on equipment.ModelID equals model.ModelID
join equipmentType in dc.tEquipmentTypes on equipment.TypeID equals equipmentType.EquipmentTypeID
join equipmentStatus in dc.tEquipmentStatus on equipment.StatusID equals equipmentStatus.EquipmentStatusID
select equipment;
Thanks inadvance.

Related

Using flat table in MVC

If I have a model that has several tables, and I am joining these tables together into a flat table within my controller class, how do I get the view to be able to access the flat table?
For example, let's say I have three tables in my model (customers, orders, invoices).
Orders are linked to customer by a foreign key (CustomerID), and invoices are linked to orders by a foreign key (OrderID).
In order to see all of this in one flat table (with all customers listed, even if they don't have orders, and all orders listed, even if they don't have invoices), I have the following anonymous type:
var FlatTable = (from a in customers
let CustomerID = a.ID
join b in orders on a.ID equals b.CustomerID into ab
from b in ab.DefaultIfEmpty()
let OrderID = b.ID
join c in invoices on b.ID equals c.InvoiceID into ac
from c in ac.DefaultIfEmpty()
let InvoiceID = c.ID
select new {a.CustomerName, CustomerID, OrderID, b.ProductDescription, InvoiceID, c.InvoiceAmount});
return View(FlatTable.ToList());
Then in my View (which is based on my model), how am I able to access FlatTable.
IList<ViewModel> model = (from a in customers
join b in orders on a.ID equals b.CustomerID into ab
from b in ab.DefaultIfEmpty()
join c in invoices on b.ID equals c.InvoiceID into ac
from c in ac.DefaultIfEmpty()
select new ViewModel() {CustomerName = a.CustomerName, CustomerID = a.ID, OrderID = b.ID, ProductDescription = b.ProductDescription, InvoiceID = c.ID, InvoiceMaount = c.InvoiceAmount}).ToList();

ASP.NET MVC 5 Join on Between, no primary key

I have some interesting code to look at.
I have three tables:
Table A has 4 columns:
TablePK
UserID
TableBFKID
Score
Table B has 3 columns:
TablePK
Name
ShortName
Table c has 4 columns:
TablePK
ScoreMin
ScoreMax
Modifier
So when the full join happens it looks like this:
SELECT B.ShortName
, A.Score
, C.Modifier
FROM TableA A
INNER JOIN TableB B ON a.TablePK= B.TablePK
INNER JOIN TableC C ON A.Score BETWEEN C.ScoreMin AND C.ScoreMax
The results would look like this:
ShortName, Score, Modifier. EX:
CHA, 19, 4
Now I know how to do an Entity Framework join if there is an actual PK or FK, or even if there is only a 0:1 relationship.
But how do you do the join when there is neither a PK nor an FK?
LINQ, including LINQ to Entities, only supports equi-joins.
But you can run SQL directly:
var res = myContext.Database.SqlQuery<TResult>("SQL goes here", parmeters...);
and EF will map the columns of the result set to the properties of TResult (which needs to other connection to the context: it does not need to be an entity type with a DbSet typed property in the context).
In this case I wouldn't try to join them, just use a sub-select in your linq to select from the un-joined table where the scores are between your wanted ranges.
var results = context.TableA
.Select(a => new {
score = a.Score, //add all needed columns
tableCs = context.TableC.Where(c => a.Score >= c.ScoreMin && a.Score <= c.ScoreMax)
});

Inner Join in LINQ not working correctly

I have the following tables in this SQL database (some fields are irrelevant to this question):
I have the following LINQ query:
Dim trips = From tr In db.tbl_Trips _
Join ds In db.tbl_tripDeptStations On tr.trip_ID Equals ds.tds_ID _
Where ds.tbl_Station.stn_County = county _
And tr.trip_StartDate >= startDate _
And tr.trip_EndDate <= endDate _
Select tr.trip_Name, tr.trip_StartDate, tr.trip_EndDate, tr.trip_SmallImage, tr.tbl_TourOperator.tourOp_Name
startDate, endDate and county are variables which I have declared in code above (not shown).
I am trying to show trips which have certain departure stations associated, based upon the county which can be found in the station table.
However, when I run the query, I get no results, and no error messages.
I also have this SQL query which works correctly:
SELECT distinct t.trip_ID, t.trip_Name, t.trip_StartDate, toop.tourOp_Name
FROM tbl_Trip AS t
INNER JOIN
(SELECT tds.tds_trip
FROM tbl_tripDeptStation AS tds
INNER JOIN tbl_station AS s
ON tds.tds_Stn = s.stn_ID
WHERE s.stn_county = 'Greater London'
) AS ds
ON t.trip_ID = ds.tds_trip
INNER JOIN tbl_TourOperator AS toop ON t.tourOp_ID = toop.tourop_id
WHERE t.trip_StartDate >= #StartDate AND t.trip_EndDate <= #EndDate
ORDER BY t.trip_
Can anyone shed some light as to where I might be going wrong?
if you're using entity framework,
var ds = from tds in tbl_tripdeptstation
join s in tbl_station on tds.tds_stn equals s.stn_id
where s.stn_country.equals("somecountry")
select new {tds.trip};
var result = (from t in tbl_trip
join ds2 in ds on t.trip_id equals ds2.trip
join toop in tbl_touroperator on t.tourop_id equals toop.tourop_id
where t.trip_start >= SomeDate AND t.trip_enddate <= EndDate
select new { t.trip_ID, t.trip_Name, t.trip_StartDate, toop.tourOp_Name}).Distinct().OrderBy(r => r.trip_);

Querying on count value having ()

I'm having difficulty with a query which displays records according to their fill rate.
For instance, a vacancy can have no bookings or some bookings. If a vacancy has bookings, they can be in the form of 'active [1]', 'pending [0]'. The query I have written so far works if the vacancy has booking records but I can't get it to work if it doesn't have booking records.
My query (which works) for vacancies with a booking is as follows:-
SELECT v.*, j.job_category_name, bu.business_unit_name
FROM vacancy v
INNER JOIN job_category j ON j.job_category_id = v.job_category_id
INNER JOIN business_unit bu ON bu.business_unit_id = v.business_unit_id
INNER JOIN booking b ON b.vacancy_id = v.vacancy_id
INNER JOIN booking_status bs ON bs.id = b.booking_status_id
WHERE
v.vacancy_status <> 'revoked' AND
v.vacancy_reference <> 'auto-generated booking' AND
v.business_unit_id IN (series of primary keys) AND
(bs.booking_status_type_id = 1 OR bs.booking_status_type_id = 2)
GROUP BY v.vacancy_id
HAVING v.vacancy_limit > count(b.booking_id)
ORDER BY v.vacancy_id DESC
I thought by changing the join of b and bs to LEFT JOIN would have worked, but it hasn't.
Any ideas?
Without a copy of your schema to work from, it's difficult to tell exactly, but when you changed booking and bookingstatus to LEFT JOINs, did you also modify your WHERE clause so that it read something like:
WHERE
v.vacancy_status <> 'revoked' AND
v.vacancy_reference <> 'auto-generated booking' AND
v.business_unit_id IN (series of primary keys) AND
(ISNULL(bs.booking_status_type_id, 1) = 1 OR ISNULL(bs.booking_status_type_id, 2) = 2)
i.e. Ensured that the full WHERE clause would be satisfied, thus not stripping out the records where all the values for columns from booking and bookingstatus were NULL?
Try LEFT OUTER JOIN for the tables for which the joins may return 0 matches.
For eg:- in your case have LEFT OUTER JOIN for b and bs and check

SQL Query Conversion to LINQ Left Outer Join (VB.NET)

I've looked all around and spent way to long trying to convert this SQL statement into a Linq statement in VB. I'm sure it would be a good example for others out there - the statement is trying to pull products that have a many-to-many relationship with product categories, and the categories have a hierarchy of parents/children.
Here is the query I am trying to convert:
SELECT P.ProductID, P.ProductName, P.ProductSlug, P.PartNumber
FROM Products AS P
INNER JOIN Products_Categories AS PC ON PC.ProductID = P.ProductID
INNER JOIN Categories AS C ON PC.CategoryID = C.CategoryID
LEFT OUTER JOIN Categories AS P_Cats ON P_Cats.CategoryID = C.Parent
WHERE (C.CategoryID = 9) OR (C.Parent = 9) OR (P_Cats.Parent = 9)
I can get up to the point where I am trying to say "WHERE ... (P_Cats.Parent = 9)" but can't figure that part out.
THANKS!
Figured it out right after posting the question, but here is the answer in case anyone else finds it helpful:
Dim query = (From products In db.Products _
Join PC In db.Products_Categories On PC.ProductID Equals products.ProductID _
Join C In db.Categories On PC.CategoryID Equals C.CategoryID _
Group Join cat In db.Categories On cat.CategoryID Equals C.Parent Into C_Parents = Group _
From cParents In C_Parents.DefaultIfEmpty() _
Where (C.CategoryID = categoryID Or C.Parent = categoryID Or cParents.CategoryID = categoryID) _
And products.IsDeleted = False)
It was the line "From cParents In C_Parents.DefaultIfEmpty()" that I was leaving out.

Resources