Linq Join Question - linq

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

Related

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 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
});

Greater Than Condition in Linq Join

I had tried to join two table conditionally but it is giving me syntax error. I tried to find solution in the net but i cannot find how to do conditional join with condition. The only other alternative is to get the value first from one table and make a query again.
I just want to confirm if there is any other way to do conditional join with linq.
Here is my code, I am trying to find all position that is equal or lower than me. Basically I want to get my peers and subordinates.
from e in entity.M_Employee
join p in entity.M_Position on e.PostionId >= p.PositionId
select p;
You can't do that with a LINQ joins - LINQ only supports equijoins. However, you can do this:
var query = from e in entity.M_Employee
from p in entity.M_Position
where e.PostionId >= p.PositionId
select p;
Or a slightly alternative but equivalent approach:
var query = entity.M_Employee
.SelectMany(e => entity.M_Position
.Where(p => e.PostionId >= p.PositionId));
Following:
from e in entity.M_Employee
from p in entity.M_Position.Where(p => e.PostionId >= p.PositionId)
select p;
will produce exactly the same SQL you are after (INNER JOIN Position P ON E..PostionId >= P.PositionId).
var currentDetails = from c in customers
group c by new { c.Name, c.Authed } into g
where g.Key.Authed == "True"
select g.OrderByDescending(t => t.EffectiveDate).First();
var currentAndUnauthorised = (from c in customers
join cd in currentDetails
on c.Name equals cd.Name
where c.EffectiveDate >= cd.EffectiveDate
select c).OrderBy(o => o.CoverId).ThenBy(o => o.EffectiveDate);
If you have a table of historic detail changes including authorisation status and effective date. The first query finds each customers current details and the second query adds all subsequent unauthorised detail changes in the table.
Hope this is helpful as it took me some time and help to get too.

Need help with designing a query in ELinq

This is my query:
Dim vendorId = 1, categoryId = 1
Dim styles = From style In My.Context.Styles.Include("Vendor") _
Where style.Vendor.VendorId = vendorId _
AndAlso (From si In style.StyleItems _
Where si.Item.Group.Category.CategoryId = _
categoryId).Count > 0 _
Distinct
I have the feeling that I can improve the performance, cuz the above query is (correct me if I am wrong) performs 2 round-trips to the server; 1 time by the Count and then when it's executed.
I want to send this Count thing to the DB so it should be only one round trip to the server.
Even it's not the exact thing, this is actually what I need:
SELECT DISTINCT Style.*
FROM Style INNER JOIN
Vendor ON Style.VendorId = Vendor.VendorId INNER JOIN
StyleItem ON Style.StyleId = StyleItem.StyleId INNER JOIN
Item ON StyleItem.ItemId = Item.ItemId INNER JOIN
[Group] ON Item.GroupId = [Group].GroupId INNER JOIN
Category ON [Group].CategoryId = Category.CategoryId
WHERE (Style.VendorId = #vendorid) AND (Category.CategoryId = #CategoryId)
I wish I could use this SPROC (i.e. function import etc.), but I need to Include("Vendor"), which constraints me to do it with Linq.
Any kind of suggestion will be really welcommed!
It is probably not doing two trips to the database. It will get optimized before it is executed, and nothing gets executed until you try the read the data.
Normally I check the SQL that is created using SQL Profiler. I have also found LinqPad to be very usefull.

converting group SQL expression into 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;

Resources