if checkbox chkAus checked :
if (chkAus.Checked)
{
vAdvanceSearchResults = (from t in vAdvanceSearchResults
join imp in _bDataContext.Imprints on t.ImprintID equals imp.ID
join cc in _bDataContext.CountryCodes on imp.CountryID equals cc.ID
where cc.Code.Contains("AU")
select t).Distinct();**
}
if chkAus and chkNz are checked
if (chkNz.Checked && chkAus.Checked)
{
vAdvanceSearchResults = (from t in vAdvanceSearchResults
join imp in _bDataContext.Imprints on t.ImprintID equals imp.ID
join cc in _bDataContext.CountryCodes on imp.CountryID equals cc.ID
where cc.Code.Contains("AU") || cc.Code.Contains("NZ")
select t).Distinct();
}
The condition on linq query changes as the checkboxes are checked.
where cc.Code.Contains("AU") || cc.Code.Contains("NZ")
I have nearly 10 checkboxes, and got stuck on how to write that many conditions.
Any help please.
for example if there is chkUS :
then the combination with chkAus,chkNz,chkUS checkboxes the linq query would change.
where cc.Code.Contains("AU") || cc.Code.Contains("NZ") || cc.Code.Contains("US")
Put all of them in a list and then do a if list.contains(cc.Code)
var a = new List<string>(){"AU","NZ","US"};
var linq = (from t in vAdvanceSearchResults
join imp in _bDataContext.Imprints on t.ImprintID equals imp.ID
join cc in _bDataContext.CountryCodes on imp.CountryID equals cc.ID
where a.Contains(cc.Code)
select t).Distinct();
Create a list of selected checkboxes first. Like this.
var selectedCountries = new List<string>();
if (chkAus.Checked) selectedCountries.Add("AU");
if (chkNz.Checked) selectedCountries.Add("NZ");
if (chkUs.Checked) selectedCountries.Add("US");
//... And so on
And then modify your linq query to check whether this list contains the code or not, I mean reversing the comparison is an answer. Make sure you remove if condition for this linq query.
vAdvanceSearchResults = (from t in vAdvanceSearchResults
join imp in _bDataContext.Imprints on t.ImprintID equals imp.ID
join cc in _bDataContext.CountryCodes on imp.CountryID equals cc.ID
where selectedCountries.Contains(cc.Code)
select t).Distinct();
This will fix your problem.
Related
I want to convert this SQL code to LINQ. Here is my SQL code:
SELECT Rooms.RoomName AS RoomNo, Beds.BedName AS Beds, Rooms.RoomType, ISNULL(CheckIn.CheckIntatus,'') AS Status
FROM CheckIn
INNER JOIN GuestBeds ON CheckIn.GuestBedId = GuestBeds.Id
AND (CheckIn.CheckInStatus = 1 OR CheckIn.CheckIntatus = 2 OR CheckIn.CheckSIntatus = 3)
RIGHT JOIN Beds ON GuestBeds.BedId = Beds.Id
INNER JOIN Rooms ON Beds.RoomId = Rooms.Id
LEFT JOIN Guests ON CheckIn.GuestId = Guests.Id
WHERE Beds.Active = 1 AND Rooms.Active = 1
ORDER BY RoomName, Beds
It works well which means it shows all the RoomName with CheckInStatus. If the Room is not presence in CheckIn table, ot will return the status as Null.
So I want to convert the code to LINQ. SO here is my LINQ code:
from b in Beds
join w in Rooms on b.RoomsId equals w.Id
where (a.CheckInStatus == 3 || a.CheckInStatus == 1 || a.CheckInStatus == 2)
join p in GuestBeds on b.Id equals p.BedId
join a in CheckIn on p.Id equals a.GuestBedId
join t in Guests on a.GuestId equals t.Id
where b.Active == true && w.Active == true
orderby w.RoomName
select new
{
RoomName = w.RoomName,
BedName = b.BedName,
Status = a.CheckInStatus
}
It didnt worked like the first code. It only show the data which contain CheckInStatus. I want it to show all the RoomName inside Room database
Normally I would post some rules for converting SQL to LINQ but this is complicated enough I think I'd need to make new rules. I commented out the references to Guests because as a LEFT JOIN it has no bearing on the answer.
Pull out the WHERE on individual tables and make them sub-queries:
var ActiveBeds = Beds.Where(b => b.Active == 1);
var ActiveRooms = Rooms.Where(r => r.Active == 1);
In LINQ, a RIGHT JOIN must be done by flipping the join to be a left join, so we will create the two sides as sub-queries.
Left side of RIGHT JOIN:
Translate the JOIN conditions that aren't part of an equi-join into a LINQ where clause on the appropriate tables (alternately this could be a subquery as above). The LEFT JOIN becomes a LINQ join/from ... DefaultIfEmpty() phrase, but as noted above isn't needed.
var CheckInsGuestBedsGuests = from c in CheckIn
where (c.CheckInStatus == 1 || c.CheckInStatus == 2 || c.CheckInStatus == 3)
join gb in GuestBeds on c.GuestBedId equals gb.Id
//join g in Guests on c.GuestId equals g.Id into gj
//from g in gj.DefaultIfEmpty()
select new { c, gb /*, g */ };
Right side of RIGHT JOIN:
The other side of the RIGHT JOIN includes an INNER JOIN so put them together in a sub-query:
var ActiveBedsRooms = from b in ActiveBeds
join r in ActiveRooms on b.RoomId equals r.Id
select new { b, r };
Finally, flip the sub-queries to create a left join using the same idiom as above:
var ans = from br in ActiveBedsRooms
join cgbg in CheckInsGuestBedsGuests on br.b.Id equals cgbg.gb.BedId into cgbgj
from cgbg in cgbgj.DefaultIfEmpty()
select new {
RoomNo = br.r.RoomName,
Beds = br.b.BedName,
br.r.RoomType,
Status = cgbg.c.CheckInStatus
};
NOTE: If you were not using LINQ to SQL, the Status expression would fail when cgbg is null and you would need
Status = cgbg?.c.CheckInStatus
but unfortunately LINQ to SQL/EF doesn't handle the null conditional operators yet.
BTW, nice query - brings back memories of when I used to write hotel front desk software :)
I'm sorry for telling that I've a little bit weak on LINQ, I always do write SQL query before I start working on the complicated LINQ.
I want to ask that how to convert this SQL Query into LINQ with LEFT JOIN with multiple ON conditons with the OR operator.,
m.MerchandiseId will be use for twice in ON condition
SELECT
*
FROM
Inbox AS i
INNER JOIN [User] AS u ON i.FromUserId = u.UserId
LEFT OUTER JOIN Merchandise AS m ON
u.MerchandiseId = m.MerchandiseId
OR
i.ToMerchantId = m.MerchandiseId
WHERE
i.ToCompanyId = 10
OR
i.FromCompanyId = 10
var message = (from i in db.Inbox
join u in db.User on i.FromUserId equals u.UserId
join m in db.Merchandise on u.MerchandiseId equals m.MerchandiseId //here I want to ON i.MerchantId = m.MerchandiseId, but it doesn't allow
where i.ToCompanyId == user.CompanyId || i.FromCompanyId == user.CompanyId
orderby i.CreatedAt descending
group m.MerchandiseId by new { m.MerchandiseId, m.MerchandiseName } into grp
select new
{
MerchandiseId = grp.Key.MerchandiseId,
MerchandiseName = grp.Key.MerchandiseName,
InboxMessage = (from e in db.Inbox
join us in db.User on e.FromUserId equals us.UserId
join mer in db.Merchandise on us.MerchandiseId equals mer.MerchandiseId
where mer.MerchandiseId == grp.Key.MerchandiseId
orderby e.CreatedAt descending
select e.InboxMessage).FirstOrDefault(),
CreatedAt = (from e in db.Inbox
join us in db.User on e.FromUserId equals us.UserId
join mer in db.Merchandise on us.MerchandiseId equals mer.MerchandiseId
where mer.MerchandiseId == grp.Key.MerchandiseId
orderby e.CreatedAt descending
select e.CreatedAt).FirstOrDefault(),
}).ToList();
The bottom LINQ Query I've write for it. However, I just can work on the left join with multiple ON clause in LINQ. Appreciate if someone would help me on this. Thanks!
I don't believe Linq supports the use of the OR operator with multiple columns, but that said, I wouldn't use OR even in SQL as it makes the join's intention unclear and it also obscures where the data originated from - it also isn't immediately clear what happens if there are multiple matches for each column. Instead I would JOIN twice on the different columns and let the projection-clause handle it:
SELECT
*
FROM
Inbox
INNER JOIN [User] AS u ON i.FromUserId = u.UserId
LEFT OUTER JOIN Merchandise AS userMerchant ON u.MerchandiseId = userMerchant.MerchandiseId
LEFT OUTER JOIN Merchandise AS inboxMerchant ON Inbox.ToMerchantId = inboxMerchant .MerchandizeId
WHERE
Inbox.ToCompanyId = 10
OR
Inbox.FromCompanyId = 10
This can then be translated into Linq using the LEFT OUTER JOIN approach ( How to implement left join in JOIN Extension method )
Note that if you're using Entity Framework then you don't need to worry about doing any of this at all! Just use Include:
var query = db.Inbox
.Include( i => i.User )
.Include( i => i.User.Merchandise )
.Include i => i.Merchandise )
.Where( i => i.ToCompanyId = 10 || i.FromCompanyId == 10 );
How can I join two different tables based on a condition?
I have my query as under:
var myquery = from p in db.tbl1
join q in db.tbl2 on p.field1 equals q.field1
join r in db.tbl3 on q.field2 equals r.field2
Till here everything is fine, now I want to add 1 more join to a table but it should be based on a condition like:
if(q.field3 == 1)
join s in db.tbl4 on q.field4 equals s.field4
else if(q.field3 == 2)
join s in db.tbl5 on ....
So basically I want to join to different tables based on the value of q.field3.
You're not going to be able to conditionally join based on the value of a single row. The idea of joining is that you're joining based off of all of the rows. Conditionally determining what/how to join based on some value outside of the query would make sense.
What you can do is do both joins unconditionally, but choose which result to use conditionally for each row. Obviously this will only work if the tables are of the same type, or if you first project s1 and s2 into a common type (using let)
var myquery = from p in db.tbl1
join q in db.tbl2 on p.field1 equals q.field1
join r in db.tbl3 on q.field2 equals r.field2
join s1 in db.tbl4 on q.field4 equals s1.field4
join s2 in db.tbl5 on q.field5 equals s2.field5
let s = q.field3 == 1 ? s1 :
q.field3 == 2 ? s2 : null
This should be able to be translated by the query provider into a CASE statement.
I have a linq query w/ entity frameworks that works and gets the needed information, but now i am having trouble doing the opposite.
Currently it gets all the data that is needed using the joins to link tables but i need to to get some data that is not match some of the joins.
I know you can only use "equals" om linq, but i need info that is not equals
i.e. join ec in c.IsoNe on ap.idLook not equals ec.idAll
Below is the working code, but not how i need it now. any help would be appreciated...
var test = (from bil in bilats
join ap in c.Allegro on bil.idAll equals ap.idAll
join ec in c.IsoNe on ap.idLook equals ec.idAll
join cb in c.Comp on ap.idCompBuy equals cb.idComp
join cs in c.Com on ap.idCompSell equals cs.idComp
join iby in c.IsoNe on cb.idComp equals iby.idComp
join iss in c.IsoNe on cs.idComp equals isl.idComp
orderby bil.HBegin ascending
where bil.HBegin >= ec.DateTStart
where bil.HBegin < ec.DateTEnd
select new
{
Cont = ec.ContractID,
ContType = ap.idScheduleType,
Sel = isel.ISONE1,
Buy = ibel.ISONE,
HBegin = bil.HBegin,
}).ToList();
As far as I know, you'll have to create a Cartesian product and then use a where-condition to filter it. (I'm making the perhaps rash assumption that you want an inner join rather than a left join, but an inner join is what the join keyword represents.) Something like this:
var test = (from bil in bilats
join ap in c.Allegro on bil.idAll equals ap.idAll
from ec in c.IsoNe where ap.idLook != ec.idAll
join cb in c.Comp on ap.idCompBuy equals cb.idComp
join cs in c.Com on ap.idCompSell equals cs.idComp
join iby in c.IsoNe on cb.idComp equals iby.idComp
join iss in c.IsoNe on cs.idComp equals isl.idComp
orderby bil.HBegin ascending
where bil.HBegin >= ec.DateTStart
where bil.HBegin < ec.DateTEnd
select new
{
Cont = ec.ContractID,
ContType = ap.idScheduleType,
Sel = isel.ISONE1,
Buy = ibel.ISONE,
HBegin = bil.HBegin,
}).ToList();
Sounds like a join might be the wrong approach. Have a look at unions or subqueries
C# linq union question
how to do subquery in LINQ
How can I make the following SQL a Linq query:
SELECT * FROM ORDERS
INNER JOIN ITEMS
ON ORDERS.ID = ITEMS.ORDER_A OR ORDERS.ID = ITEMS.ORDER_B
I would think it would be:
from o in orders
join i in items
on o.ID equals i.OrderA or o.ID equals i.OrderB
select new { Order = o, Item = i }
I'm guessing the compiler wants something else. How do I write this statement?
You have to make two joins
from o in orders
join iA in items on o.ID equals iA.OrderA
join iB in items on o.ID equals iB.OrderB
set i = (iA == null ? iB : iA)
select new { Order = o, Item = i }
Didn't actually try compile this, but basically this is what you have to do, two different joins that you pick before it is being selected out to the array.
What you would want to use is http://msdn.microsoft.com/en-us/library/bb549267.aspx, unfortunately I don't think that will translate very well to SQL and can only be used as an extension method.
Though perhaps you can use a cross-join and filter it in the where condition? I would verify the generated SQL first though before using this method.
from o in orders
from i in items
where o.ID == i.OrderA || o.ID == i.OrderB
select new { Order = o, Item = i }