converting group SQL expression into LINQ - linq

I am having a real pain in converting this query expression into my LINQ expression.
SELECT
r.Disc_code
,r.SEX
FROM RACE r
WHERE r.EVENT_CODE = 100
GROUP BY
r.SEX
, r.disc_Code
order by r.disc_code
i can work with one table but i have not seen any example which chains two group expressions in stackoverflow or MSDN. Am i missing some thing ?

Maybe something like this:
var results = from r in dataContext.Race
where r.EVENT_CODE == 100
orderby r.Disc_Code ascending
group r by new { r.Sex, r.Disc_Code } into g
select g.Key;

Here's an example of grouping by multiple columns in VB.NET.
Dim query = From r In db.Race _
Where r.EVENT_CODE = 100 _
Order By r.disc_Code _
Group By Key = New With {r.Sex, r.disc_Code} Into Group _
Select Key, Group

to group on multiple criteria you have to do something like this:
var query = from book in books
group book by new {book.author, book.editor} into books;
to access them:
var author = books.Key.author;
var editor = books.Key.editor;

Related

LINQ Query To Return Duplicates Exclusively

I'm working on this LINQ query. I'd like the resulting list return a list of records that contain duplicates exclusively, based on the EMailAddress1 field and grouped by the EMailAddress1 field.
For instance:
emailaddress1#gmail.com
emailaddress1#gmail.com
emailaddress2#gmail.com
emailaddress2#gmail.com
emailaddress2#gmail.com
emailaddress3#gmail.com
emailaddress3#gmail.com
etc.
Any advice on this? Thanks.
var contacts = (from c in xrm.ContactSet
where c.StateCode != 1
orderby c.EMailAddress1, c.CreatedOn
descending select new {
c.FirstName,
c.LastName,
c.EMailAddress1,
c.ContactId,
c.CreatedOn }).ToList();
Based on your previous query:
var duplicatedEmails = (from c in contacts
group c by c.EMailAddress1 into g
where g.Count() > 1
select g.Key).ToList();
var duplicatedContacts = contacts.Where(c => duplicatedEmails.Contains(c.EMailAddress1));

Linq and grouping with three tables

I've come up with the following LINQ, but I can't help thinking that I should be able to do this in one query instead of two. Can anyone help?
The idea is to inner join three tables and group by one.
var q1 = from er in ExportRules
join per in PlaceExportRules on er.ExportRulesID equals per.ExportRulesID
select new
{
PlaceID = per.PlaceID,
Description = er.Description,
Tag = er.TagName,
ExportName = per.ExportName,
ExportAddress = per.ExportAddress
};
var q2 = from p in Places
join rules in q1 on p.PlaceID equals rules.PlaceID into joined2
where joined2.Any()
orderby p.PlaceName
select new {Place = new {p.PlaceID, p.PlaceName}, joined2};
Well, you can just bracket things:
var query = from p in Places
join rules from
(from er in ExportRules
join per in PlaceExportRules
on er.ExportRulesID equals per.ExportRulesID
...)
on p.PlaceId equals rules.PlaceId into joined2
where joined2.Any()
orderby p.PlaceName
select new {Place = new {p.PlaceID, p.PlaceName}, joined2};
However, I'd personally probably leave it as two queries. It's clearer, and won't affect the performance - it's not like the first statement in your code would actually execute the query.

LINQ to Entities three table join query

I'm having a bit trouble with a query in Linq to Entities which I hope someone can shed a light on :-) What I'm trying to do is to create a query that joins three tables.
So far it works, but since the last table I'm trying to join is empty, the result of the query doesn't contain any records. When I remove the last join, it gives me the right results.
My query looks like this:
var query = from p in db.QuizParticipants
join points in db.ParticipantPoints on p.id
equals points.participantId into participantsGroup
from po in participantsGroup
join winners in db.Winners on p.id
equals winners.participantId into winnersGroup
from w in winnersGroup
where p.hasAttended == 1 && p.weeknumber == weeknumber
select new
{
ParticipantId = p.id,
HasAttended = p.hasAttended,
Weeknumber = p.weeknumber,
UmbracoMemberId = p.umbMemberId,
Points = po.points,
HasWonFirstPrize = w.hasWonFirstPrize,
HasWonVoucher = w.hasWonVoucher
};
What I would like is to get some records even if the Winners table is empty or there is no match in it.
Any help/hint on this is greatly appreciated! :-)
Thanks a lot in advance.
/ Bo
If you set these up as related entities instead of doing joins, I think it will be easier to do what you're trying to do.
var query = from p in db.QuizParticipants
where p.hasAttended == 1 && p.weeknumber == weeknumber
select new
{
ParticipantId = p.id,
HasAttended = p.hasAttended,
Weeknumber = p.weeknumber,
UmbracoMemberId = p.umbMemberId,
Points = p.ParticipantPoints.Sum(pts => pts.points),
HasWonFirstPrize = p.Winners.Any(w => w.hasWonFirstPrize),
HasWonVoucher = p.Winners.Any(w => w.hasWonVoucher)
};
This is assuming hasWonFirstPrize and hasWonVoucher are boolean fields, but you can use any aggregate function to get the results you need, such as p.Winners.Any(w => w.hasWonFirstPrize == 1)
I don't use query syntax a lot but I believe you need to change from w in winnersGroup to from w in winnersGroup.DefaultIfEmpty()

LINQ Query Similar to SQL WHERE x IN

I have a need to create a LINQ query that returns results based on a subquery. Not quite sure I'm wording that properly but the best way I know to ask is to show an example. How can I turn the following TSQL query into a LINQ query (tables are same name as objects):
SELECT CuisineId, Name
FROM Cuisine
WHERE CuisineId NOT IN (SELECT CuisineId
FROM RestaurantCuisine
WHERE RestaurantId = #id)
As you can guess, I'm trying to get a list of "available" cuisines to be listed for a user to add to a list of cuisines that a restaurant offers. The LINQ I have thus far returns ALL cuisines and doesn't take in account of the existing CuisineId's that have already been added to the other table:
I've looked all over for an example but not quite sure how to describe exactly what I need. I looked at the MSDN reference for LINQ queries but couldn't find anything like what I need:
MSDN LINQ Sample Queries
Anyone able to give me an example?
In C#:
var query =
from c in db.Cuisine
where !(from rc in db.RestaurantCuisine
where rc.RestaurantId == id
select rc.CuisineId)
.Contains(c.CuisineId)
select new {
c.CuisineId,
c.Name
};
In VB.NET:
Dim availableCuisines = _
From c In db.Cuisines _
Where Not (From rc In db.RestaurantCuisines _
Where rc.RestaurantId = id _
Select rc.CuisineId) _
.Contains(c.CuisineId) _
Select c
var cuisines = db.Cuisine.Where(c => !RestaurantCuisine.Any(
rc => rc.RestaurantId == c.Id && rc.CuisineId == c.CuisineId);
Try:
Cuisine.Where(c => !RestaurantCuisine.Select(rc => rc.CuisineID).Contains(c.CuisineID)).Select(c => c);
var query = (from c in Cuisine
where !(from rest in RestaurantCuisine
where (rest.RestaurantID == id)).Contains(c.CuisineId)
select new
{
CuisineID = c.CuisineID,
Name = c.Name
});

Linq Join Question

I have a problem trying to do a couple of things with linq joins... currently I have a
group in linq that gives two columns, basically a count of tickets by location. Well now I'm trying to add a join that will join on the ticketID columns of two different tables Tickets and Comments.
I'm having a hell of a time trying to convert the sql join into Linq, less alone merging that into my original total count linq statement...somebody please help!
Original Linq statement:
From p In NewTickets _
Where p.TDate > "06/01/2009 12:00:00AM" And p.TDate < "07/01/2009 12:00:00PM" _
Group p By p.LocationID _
Into Count() _
Select _
LocationID, _
NoOfTickets = Count _
Order By NoOfTickets Descending
Join I need merged into Linq statement:
SELECT *
FROM NewTickets as p
LEFT OUTER JOIN NewComments AS c ON p.TicketID = c.TicketID
WHERE (p.TDate > '06/01/2009 12:00:00AM') And (p.TDate < '07/01/2009 12:00:00PM')
AND c.Comment Like '%ali%'
THANK YOU!
If you add a relationship in the linq to sql designer between NewTickets and NewComments, properties will be created on those classes to navigate.
Queries that use those properties will automatically translate into the join. For example:
from t in db.NewTickets
where t.NewComments.Any(nc => nc.Comment.Contains("ali"))
group t by t.LocationID into g
select new {LocationID = g.Key, NoOfTickets = g.Count()} into x
order x by x.NoOfTickets descending
select x;
Apologies for the C# code examples.
Also, I'd like to point out that the left join in your sql is moot - tickets that have no comments will be removed by the ali criteria. An inner join will do fine.
Something like this
var movies = NewTickets.Join(NewComments, x => x.TicketID, y => y.TicketID, (x, y) => x).ToList();
That was it...for the most part...I'm going to have to attack this a different way as now I'm getting a count that apparently from comments as my total has ballooned from under 200 to almost 1300...each ticket will have on average around 5 or so comments so that's why I assuming this just shooting from the hip...
Thank you David and no problem with the C# (as much that I have translated, you think I'd be using it by now).
For anyone using VB that would like to see the same in VB, here you go:
Dim q = From e In db.NewTickets _
Where e.NewComments.Any(Function(nc) nc.Comment.Contains("ali")) _
Group e By e.LocationID _
Into Count() _
Select _
LocationID, _
NoOfTickets = Count _
Order By NoOfTickets Descending

Resources