Converting order by case to Linq statement - linq

I have a query such as;
select * from TABLE_DEF_ROLE order by case when RoleName = 'Select All' then 0 else 1 end, RoleName
I have checked the related questions and answers but still couldn't figure it out. How would I translate it into a linq statement?

You can try this:
var roles = from r in db.Roles
orderby r.RoleName == "Select All" ? 0 : 1 descending
select r;
(Roles entity refers to your table)

Related

Transform Sql to EF Core Linq query

I am trying to translate the following query from SQL to EF Core. I can easily just use a stored procedure (I already have the SQL), but am trying to learn how some of the linq queries work. Unfortunately this is not by any means an ideal database schema that I inherited and I don't have the time to convert it to something better.
DECLARE #userId INT = 3
SELECT *
FROM dbo.CardGamePairs
WHERE EXISTS (SELECT 1
FROM dbo.Users
WHERE Users.Id = CardGamePairs.player1Id
AND Users.userId = #userId)
UNION
SELECT *
FROM dbo.CardGamePairs
WHERE EXISTS (SELECT 1
FROM dbo.Users
WHERE Users.Id = TableB.player2Id
AND Users.userId = #userId)
So basically I have an id that can exist in one of two separate columns in table b and I don't know in which column it may be in, but I need all rows that have that ID in either column. The following is what I tried to make this work:
//Find data from table A where id matches (part of the subquery from above)
var userResults = _userRepository.GetAllAsQueryable(x => x.userId == userId).ToList();
//Get data from table b
var cardGamePairsResults = _cardGamePairsRepository.GetAllAsQueryable(x => userResults .Any(y => y.userId == x.player1Id || y.userId == x.player2Id));
When I run the code above I get this error message:
predicate: (y) => y.userId == x.player1Id || y.userId == x.player2Id))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync().
Any ideas on how I can make this work? (I tried changing the column and table names to something that would actually make sense, hopefully I didn't miss any spots and make it more confusing.)
Because you are already have user id use it to query both columns.
var userResults = _userRepository
.GetAllAsQueryable(x => x.userId == userId)
.ToList();
var cardGamePairsResults = _cardGamePairsRepository
.GetAllAsQueryable(x => x.player1Id == userId || x.player2Id == userId));

SQL to LINQ with JOIN and SubQuery

I have a query that I' struggling to convert to LINQ. I just can't get my head around the required nesting. Here's the query in SQL (just freehand typed):
SELECT V.* FROM V
INNER JOIN VE ON V.ID = VE.V_ID
WHERE VE.USER_ID != #USER_ID
AND V.MAX > (SELECT COUNT(ID) FROM VE
WHERE VE.V_ID = V.ID AND VE.STATUS = 'SELECTED')
The Closest I've come to is this:
var query = from vac in _database.Vacancies
join e in _database.VacancyEngagements
on vac.Id equals e.VacancyId into va
from v in va.DefaultIfEmpty()
where vac.MaxRecruiters > (from ve in _database.VacancyEngagements
where ve.VacancyId == v.Id && ve.Status == Enums.VacanyEngagementStatus.ENGAGED
select ve).Count()
...which correctly resolves the subquery from my SQL statement. But I want to further restrict the returned V rows to only those where the current user does not have a related VE row.
I've realised that the SQL in the question was misleading and whilst it led to technically correct answers, they weren't what I was after. That's my fault for not reviewing the SQL properly so I apologise to #Andy B and #Ivan Stoev for the misleading post. Here's the LINQ that solved the problem for me. As stated in the post I needed to show vacancy rows where no linked vacancyEngagement rows existed. The ! operator provides ability to specify this with a subquery.
var query = from vac in _database.Vacancies
where !_database.VacancyEngagements.Any(ve => (ve.VacancyId == vac.Id && ve.UserId == user.Id))
&& vac.MaxRecruiters > (from ve in _database.VacancyEngagements
where ve.VacancyId == vac.Id && ve.Status == Enums.VacanyEngagementStatus.ENGAGED
select ve).Count()
This should work:
var filterOutUser = <userId you want to filter out>;
var query = from vac in _database.Vacancies
join e in _database.VacancyEngagements
on vac.Id equals e.VacancyId
where (e.UserId != filterOutUser) && vac.MaxRecruiters > (from ve in _database.VacancyEngagements
where ve.VacancyId == vac.Id && ve.Status == Enums.VacanyEngagementStatus.ENGAGED
select ve).Count()
select vac;
I removed the join to VacancyEngagements but if you need columns from that table you can add it back in.

How to convert following SQL query to Lambda expression?

I have a following SQL query how can I convert to lambda expression
select * from ContractItems
where ID in (SELECT distinct contractItemId from ContractPackageItems
where contractPackageId in (SELECT ID from ContractPackage
where ContractID = 680))
from the above query I need to know if row exist or not. If row exist then return true.
-TIA
---Update---
Here is what I got but it is not working
(from contractItem in _entities.ContractItems
where contractItem.ID == (from contractPackageItems in _entities.ContractPackageItems
where contractPackageItems.ContractPackageID == (from contractPackage in _entities.ContractPackages where contractPackage.ContractID == contractId select contractPackage.ID) select contractPackageItems.ContractItemId).Distinct()).Any();
Will this not do what you want?
var results = (from ci in _entities.contractItems
join cpi in _entities.contractPackageItems on ci.ID equals cpi.contractItemId
join cp in _entities.contractPackage on cpi.contractPackageId equals cp.ID
where cp.ContractID = 680
select ci).Any();

Linq: Orderby when including multiple tables

Currently learning Linq to Entity. I been successful, but came stumped with the orderby clause and its use with multiple tables.
var query = from k in contxt.pages.Include("keywords")
where k.ID == vals.pageId select k;
My understanding with the code above is it creates an inner join where ID is equal to pageId.
So what I am having a difficult time visualizing is how I would perform an orderby on both tables?
I would like to sort on both tables.
I have tried:
var query = from k in contxt.pages.Include("keywords") where k.ID == vals.pageId orderby k.keywords.**?** select k;
The question mark is not supposed to be there. I am showing that the column that I would like to sort by isn't there. Trying this k.Kegwords. doesn't show the column.
I would write a SQL query as follows:
string query = "SELECT pages.page, pages.title, pages.descp, keywords.keyword
FROM pages INNER JOIN keywords ON pages.ID = keywords.pageID
ORDER BY keywords.sort, pages.page";
pages and keywords have a 1 to many relationship, which FK keywords.
Thank you,
deDogs
Here you go.
var result = (from x in pages
join y in keywords on x.ID equals y.pageID
orderby y.sort, x.page
select new
{
x.Page,
x.title,
x.descp,
y.keyword
});

Entity Framework T-Sql "having" Equivalent

How can I write a linq to entities query that includes a having clause?
For example:
SELECT State.Name, Count(*) FROM State
INNER JOIN StateOwner ON State.StateID = StateOwner.StateID
GROUP BY State.StateID
HAVING Count(*) > 1
Any reason not to just use a where clause on the result?
var query = from state in states
join stateowner in stateowners
on state.stateid equals stateowner.stateid
group state.Name by state.stateid into grouped
where grouped.Count() > 1
select new { Name = grouped.Key, grouped.Count() };
I believe you can use a GroupBy followed by a Where clause and it will translate it as a Having. Not entirely sure though.
If you want to compare a variable that is not in the group by (Ex: age), then it would be:
var duplicated = (
from q1 in db.table1
where (q1.age >= 10 )
group q1 by new { q1.firstName, q1.lastName } into grp
where (grp.Count() > 1 )
select new
{
firstName= grp.Key.firstName,
lastName = grp.Key.lastName,
}
);

Resources