SQL INNER JOIN with WHERE clause to LINQ format - sql

How would I convert this sql query to LINQ?
SELECT company.ticker, company.primary_analyst,
personnel.last_name, company.research_associate,
company.secondary_associate, company.coverage_status
FROM company
INNER JOIN personnel ON company.primary_analyst = personnel.dpinitials
WHERE personnel.last_name='marley' AND company.associate='ml'
ORDER BY company.coverage_status

It's pretty similar:
var results = from c in company
join p in personnel on c.primary_analyst equals p.dpinitals
where p.last_name == 'marley' and c.associate == 'ml'
orderby c.coverage_status asc
select new
{
c.ticker, c.primary_analyst, p.last_name, c.research_associate,
c.secondary_associate, c.coverage_status
};
Above projects to an anonymous class with the properties you want - if you have an equivalent POCO class in your model you should project to that, if not in many cases you probably should create one.

The solution from #BrokenGlass is perfectly fine.
However, if you have a 1..many relationship it is rarely necessary to use the join operator in LINQ. In this example, if company->personell was 1..many, I would write the query like this:
var results = from c in company
where c.associate == "ml"
from p in c.personnel
where p.last_name == "marley"
orderby c.coverage_status asc
select new
{
c.ticker,
c.primary_analyst,
p.last_name,
c.research_associate,
c.secondary_associate,
c.coverage_status
};
This can also be written using the expression chain syntax:
var results = company.Where(c => c.associate == "ml")
.SelectMany(c => c.personnel, (c, p) => new
{
c.ticker,
c.primary_analyst,
p.last_name,
c.research_associate,
c.secondary_associate,
c.coverage_status
})
.Where(x => x.last_name == "marley")
.OrderBy(x => x.coverage_status)

var list = (from u in db.Users
join c in db.Customers on u.CustomerId equals c.CustomerId
where u.Username == username
select new {u.UserId, u.CustomerId, u.ClientId, u.RoleId, u.Username, u.Email, u.Password, u.Salt, u.Hint1, u.Hint2, u.Hint3, u.Locked, u.Active,c.ProfilePic}).First();

Related

SQL Query to LINQ Lambda expression

I am trying to convert a bit of SQL containing a LEFT OUTER JOIN with a GROUP BY clause into a LINQ Lambda expression.
The SQL I need to convert is:-
SELECT m.MemberExternalPK
FROM Member.Member AS m LEFT OUTER JOIN Member.Account AS a ON m.MemberID = a.MemberID
GROUP BY MemberExternalPK
HAVING COUNT(AccountID) = 0
I have managed to get it working correctly with an INNER JOIN between Member and Accounts like this (for a count of Account = 1) but this does not work for Accounts with a count of 0 (hence the LEFT OUTER JOIN is required):-
Members.Join(Accounts, m => m.MemberID, a => a.MemberID, (m, a) => new {m, a})
.GroupBy(t => t.m.MemberExternalPK, t => t.a)
.Where(grp => grp.Count(p => p.AccountID != null) == 1)
.Select(grp => grp.Key)
I have been trying to experiment with the .DefaultIfEmpty() keyword but have so far been unsuccessful. Any help would be greatly appreciated :)
I think this is what you're after:
Query syntax
var members = new List<Member>
{
new Member {MemberId = 1, MemberExternalPk = 100},
new Member {MemberId = 2, MemberExternalPk = 200}
};
var accounts = new List<Account>
{
new Account {AccountId = 1, MemberId = 1}
};
var query =
from m in members
join a in accounts on m.MemberId equals a.MemberId into ma
from ma2 in ma.DefaultIfEmpty()
where ma2 == null
group ma2 by m.MemberExternalPk into grouped
select new {grouped.Key};
The result of this example is that only the number 200 is returned. As it will only return the MemberExternalPk for members that don't have an account. i.e. As MemberId 2 doesn't have a related Account object, it is not included in the reuslts.
var list = members.GroupJoin(accounts,m=>m.MemberId, a => a.MemberId,
(m,a) => new {m,a})
.Where(x=>x.a.Count()==0)
.Select(s=>s.m.MemberExternalPk);

How can I write this query in linq?

I know there are probably a ton of questions like this already but i'm having trouble
select *
from [Group]
where GroupId not in
(select GroupId
from CustomerGroup
where CustomerId = 189621)
i have myGroups = db.Groups.Where(e=> e.GroupId), but how do i say not in?
i am kind of there
var myGroups = from a in db.Groups
where!(from b in db.CustomerGroups
where b.CustomerId == customer.CustomerId )
var groupIds = from cg in db.CustomerGroups
where cg.CustomerId == 189621
select cg.GroupId;
var myGroups = from g in db.Groups
where !groupIds.Contains(g.GroupId)
select g;
Need a list to disqualify first. NOT IN is basically a !(IEnumerable).Contains() in LINQ (since you're comparing to a set).
Using lambda expression, you probably can do it like this
var groupIds = db.CustomerGroups.Where(x => x.CustomerId == 189621).Select(x => x.GroupId);
var myGroups = db.CustomerGroups.Where(x => !groupIds.Contains(x.GroupId)).ToList();

I need help re-writing a SQL query into LINQ format

I'm not good with LINQ yet and could use some help with the syntax.
Thanks!
The below query needs to be written in LINQ for C#.
SELECT Galleries.GalleryTitle, Media.*
FROM Galleries
INNER JOIN Media ON Galleries.GalleryID = Media.GalleryID
WHERE (Galleries.GalleryID = 150)
ORDER BY MediaDate DESC, MediaID DESC
Or with query syntax:
var query = from g in db.Galleries
join m in db.Media on g.GalleryID equals m.GalleryID
where g.GalleryID == 150
orderby m.MediaDate descending, m.MediaID descending
select new { g.GalleryTitle, Media = m };
Something like this:
var query = db.Galleries
.Join(db.Media, g => g.GalleryID, m => m.GalleryID, (g, m) => new {g, m})
.Where(r.g.GalleryID == 150)
.Select(res => new {res.g.GalleryTitle, Media = res.m}
.OrderByDescending(o => o.Media.MediaDate)
.ThenByDescending(o => o.Media.MediaID);

Making thing more succint using linq to entities for inner joins

Any way to make this less verbose?
var model =
(
from MvrTable in
LinqEntitiesCtx.Mvrs
join MvrMedsTable in LinqEntitiesCtx.MvrMeds
.Where(Id => Id.FKMvrId == 1)//inner join will be fast with this!
on MvrTable.PKMvrId equals MvrMedsTable.FKMvrId
join MvrLocationTable in LinqEntitiesCtx.MvrLocations
on MvrTable.PKMvrId equals MvrLocationTable.FKMvrId
join MvrEmployeeTable in LinqEntitiesCtx.MvrEmployees
on MvrTable.PKMvrId equals MvrEmployeeTable.FKMvrId
//notice i am using a different primary key that previouslly
join MvrMedsAdminRouteTable in LinqEntitiesCtx.MvrMedsAdminRoutes
on MvrMedsTable.PKMvrMedsId equals MvrMedsAdminRouteTable.FKMvrMedsId
select new
{ //here I choose the columns I want to display
MvrTable.PKMvrId,
MvrTable.VarianceDescription,
MvrTable.CaseNumber,
MvrTable.DateOfReport,
MvrTable.DateOfVariance
}
);
Equivalent SQL code of above:
SELECT [t0].[PKMvrId], [t0].[VarianceDescription], [t0].[CaseNumber], [t0].[DateOfReport], [t0].[DateOfVariance], [t1].[PKMvrMedsId]
FROM [Mvrs] AS [t0]
INNER JOIN [MvrMeds] AS [t1] ON ([t0].[PKMvrId]) = [t1].[FKMvrId]
INNER JOIN [MvrLocations] AS [t2] ON ([t0].[PKMvrId]) = [t2].[FKMvrId]
INNER JOIN [MvrEmployees] AS [t3] ON [t0].[PKMvrId] = [t3].[FKMvrId]
INNER JOIN [MvrMedsAdminRoutes] AS [t4] ON ([t1].[PKMvrMedsId]) = [t4].[FKMvrMedsId]
WHERE [t1].[FKMvrId] =ParamMvrId
By using Associations it could probably be written more compact. Something like (not complete):
var model = from MvrTable in LinqEntitiesCtx.Mvrs
where MvrTable.MvrMeds.MvrLocations.Any() //These are the Associations
select new
{
MvrTable.PKMvrId,
MvrTable.VarianceDescription,
MvrTable.CaseNumber,
MvrTable.DateOfReport,
MvrTable.DateOfVariance
};
You don'y really need the joins since you are not getting any data from those tables. You should use Any instead which corresponds to SQL's EXISTS.
I believe changing the join's to from's will make it more clear. You could also abbreviate your entity alias's
var model =
(
from MvrTable in LinqEntitiesCtx.Mvrs
from MvrMedsTable in LinqEntitiesCtx.MvrMeds
.Where(Id => Id.FKMvrId == 1)
.Where(x => MvrTable.PKMvrId == x.FKMvrId)
from MvrLocationTable in LinqEntitiesCtx.MvrLocations
.Where(x => MvrTable.PKMvrId == x.FKMvrId)
from MvrEmployeeTable in LinqEntitiesCtx.MvrEmployees
.Where(x => MvrTable.PKMvrId == x.FKMvrId)
from MvrMedsAdminRouteTable in LinqEntitiesCtx.MvrMedsAdminRoutes
.Where(x => MvrMedsTable.PKMvrMedsId == x.FKMvrMedsId)
select new
{
MvrTable.PKMvrId,
MvrTable.VarianceDescription,
MvrTable.CaseNumber,
MvrTable.DateOfReport,
MvrTable.DateOfVariance
}
);

Complex SQL to LINQ conversion with subquery

I am trying to convert this expression into LINQ from SQL, but a bit too difficult for me, maybe you can help me with this!
SELECT TOP (2) RecipeID, UserID, Name, Servings, PreparationTime, TotalTime, DifficultyLevelID, CuisineID, DishID, MainIngredientID, PriceLevelID, FlavourID, Instructions,
Notes, Thumbnail, VideoLink
FROM dbo.Recipes
WHERE (RecipeID NOT IN
(SELECT DISTINCT Recipes_1.RecipeID
FROM dbo.Allergies INNER JOIN
dbo.UsersAllergies ON dbo.Allergies.AllergyID = dbo.UsersAllergies.AllergyID INNER JOIN
dbo.IngredientsAllergies ON dbo.Allergies.AllergyID = dbo.IngredientsAllergies.AllergyID INNER JOIN
dbo.Ingredients ON dbo.IngredientsAllergies.IngredientID = dbo.Ingredients.IngredientID INNER JOIN
dbo.RecipesIngredients ON dbo.Ingredients.IngredientID = dbo.RecipesIngredients.IngredientID INNER JOIN
dbo.Recipes AS Recipes_1 ON dbo.RecipesIngredients.RecipeID = Recipes_1.RecipeID INNER JOIN
dbo.Users ON dbo.UsersAllergies.UserID = dbo.Users.UserID INNER JOIN
dbo.AllergyFactors ON dbo.IngredientsAllergies.AllergyFactorID = dbo.AllergyFactors.AllergyFactorID
WHERE (dbo.Users.UserID = 3) AND (dbo.AllergyFactors.AllergyFactorID < 3)))
It would be easier to help you if you showed us what you have already tried, but a Linq expression like this should give you the same result set
var query = (from rec in context.Recipes
where !(from al in context.Allergies
from ua in context.UsersAllergies.Where(x => al.AllergyID == x.AllergyID)
from ia in context.IngredientsAllergies.Where(x => al.AllergyID == x.AllergyID)
from in in context.Ingredients.Where(x => ia.IngredientID == x.IngredientID)
from ri in context.RecipesIngredients.Where(x => in.IngredientID == x.IngredientID)
from re in context.Recipes.Where(x => ri.RecipeID == x.RecipeID)
from us in context.Users.Where(x => ua.UserID == x.UserID)
from af in context.AllergyFactors.Where(x => ia.AllergyFactorID == x.AllergyFactorID)
where us.UserID == 3 && af.AllergyFactorID < 3
select re.RecipeID)
.Distinct()
.Contains(rec.RecipeID)
select new
{
rec.RecipeID,
rec.UserID,
rec.Name,
rec.Servings,
rec.PreparationTime,
rec.TotalTime,
rec.DifficultyLevelID,
rec.CuisineID,
rec.DishID,
rec.MainIngredientID,
rec.PriceLevelID,
rec.FlavourID,
rec.Instructions,
rec.Notes,
rec.Thumbnail,
rec.VideoLink
}).Take(2);