Linq To SQL and Having - c#

I am fairly new to Linq To SQL but trying to run what should be a fairly simple SQL query and can't figure out how to make it play nice in LINQ.
SELECT Users.Id, Users.Id AS Expr1, Users.FirstName, Users.LastName,
User_x_Territory.UserID
FROM Users LEFT OUTER JOIN
User_x_Territory ON User_x_Territory.UserID = Users.Id
GROUP BY Users.Id, Users.Id, Users.FirstName, Users.LastName, User_x_Territory.UserID
HAVING (COUNT(User_x_Territory.UserID) = 0)
Just trying to get all users that do not have a territory assigned, the only way to tell if they have a territory is to check the user_x_territory gerrund.
I am able to get all of the users out of my DB with this:
var users = from u in db.Users
join uXt in db.User_x_Territories on u equals uXt.User into gerr
from users in gerr.DefaultIfEmpty()
select users;
But from there I can't figure out how to add a group by/having to refine the search results to only show users with no territories.
Thanks for any help.

I suggest the following solution.
db.Users.Where(u => u.User_x_Territories.Count == 0)

edit: heh, guess someone beat me to it :(
from t in db.Users
join t0 in db.User_x_Territory on new { UserID = t.Id } equals new { UserID = t0.UserID } into t0_join
from t0 in t0_join.DefaultIfEmpty()
group new {t, t0} by new {
t.Id,
Column1 = t.Id,
t.FirstName,
t.LastName,
t0.UserID
} into g
where g.Count() == 0
select new {
Id = g.Key.Id,
Expr1 = g.Key.Id,
g.Key.FirstName,
g.Key.LastName,
UserID = g.Key.UserID
}

I don't know how efficient this is (I'm guessing not very), but you could try something like this:
var users = (from u in db.Users
join uXt in db.User_x_Territories on u equals uXt.User into gerr
from users in gerr.DefaultIfEmpty()
select u).Where(u => u.User_x_Territories.Count == 0);

Related

Linq join and group by together on multiple fields and truncate time in date

I have following Sql query which joins two table and group by date and user Id
User Table
UserName UserId
LookupScannedHistory
HistoryId UserId ScannedDate ScannedCount
I have written following sql query to join table and group by on userId and Scanned Date removing Time varaint
SELECT
l.[UserID]
,CAST([ScannedDate] AS DATE)
,Sum([ScannedCount])
,[UserName]
FROM [dbo].[LookupScannedHistory] l
Join [dbo].[UserMaster] u
on l.UserID = u.UserId
group by l.UserId, u.UserName, CAST([ScannedDate] AS DATE)
I want to convert this into linq.
I have tried this
(from log in dataContext.LookupScannedHistories
join user in dataContext.UserMasters
on log.UserID equals user.UserId
where log.ScannedDate >= fiveDayPriorDate
orderby log.ScannedDate
group log by new
{
ScannedDateOnly = EntityFunctions.TruncateTime(log.ScannedDate),
log.UserID
} into dateClickedHistory
select dateClickedHistory
).ToList();
I have done this this gives what I want but I am unable to include username by combining join and group by
I found the solution.
var usersReportGroupList = (from log in dataContext.LookupScannedHistories
join user in dataContext.UserMasters
on log.UserID equals user.UserId
where log.ScannedDate >= fiveDayPriorDate
orderby log.ScannedDate
group new { user.UserName, log.ScannedCount,
log.ScannedDate}
by new
{
ScannedDateOnly =
EntityFunctions.TruncateTime(log.ScannedDate),
log.UserID,
user.UserName
}
into dateClickedHistory
select dateClickedHistory
).ToList();
var usersReportList = new List<LookupScannedHistoryDetails>();
foreach (var group in usersReportGroupList)
{
usersReportList.Add(new LookupScannedHistoryDetails()
{
ScannedCount = group.Sum(x => x.ScannedCount.Value),
ScannedDate = group.Key.ScannedDateOnly.Value,
UserId = group.Key.UserID.Value,
UniqueCount = group.Count(),
UserName = group.Key.UserName
});
}

Sql server query equivalent in LINQ

I am trying to convert the following query in LINQ, tried different links but no luck so far. Please help with below:
SELECT T.TASKID,
T.TITLE,
T.DESCRIPTION,
T.DEADLINE,
T.CREATEDON,
(SELECT EMAIL FROM ASPNETUSERS WHERE ID = T.CREATEDBYUSERID) AS INITIATEDBY
FROM TBL_TASKMEMBERS AS M
INNER JOIN TBL_TASKS AS T ON M.TASKID = T.TASKID
INNER JOIN ASPNETUSERS AS U ON M.USERID = U.ID
WHERE m.UserId = '95d2f49c-0ae6-4571-9d7b-1c498ad0bfac'
Thanks in advance !
Try this:
var result =
from member in TBL_TASKMEMBERS
join task in TBL_TASKS on member.TASKID equals task.TASKID
join user in ASPNETUSERS on user.ID equals member.USERID
join usermail in ASPNETUSERS on usermail.ID equals task.CREATEDBYUSERID
where member.UserId = '95d2f49c-0ae6-4571-9d7b-1c498ad0bfac'
select new { TASKID = task.TASKID, TITLE = task.TITLE, DESCRIPTION = taks.DESCRIPTION, DEADLINE = task.DEADLINE, CREATEDON = task.CREATEDON, INITIATEDBY = usermail.EMAIL };

SQL to Linq Conversion Issue

Can someone help me convert a sql statement to linq? I can do very basic statement but I get confused when dealing with several joins and unions when using linq. Here is the SQL statement that I am trying to convert:
SELECT UserName, UPPER(FirstName) as FirstName, UPPER(LastName) as LastName
FROM PDDA.dbo.Users
WHERE Cono = " & Cono & "
UNION
SELECT u.UserName, UPPER(FirstName) as FirstName, UPPER(LastName) as LastName
FROM PDDA.dbo.GroupMembers g
JOIN PDDA.dbo.UserGroups ug
on ug.groupid = g.groupid
JOIN PDDA.dbo.Users u
on u.username = g.username
WHERE ug.GroupName = 'AP Department' OR ug.GroupName = 'MIS'
ORDER BY LastName, FirstName")
And here is my attempt so far:
var userDb = new PDDAEntities();
var users =
((from user in userDb.Users select user.UserName).Union(from gm in userDb.GroupMembers
join ug in userDb.UserGroups on gm.GroupID equals ug.GroupID
(from u in userDb.Users join ))
select user.UserName;
Break it down and it becomes easier. First step, the first part:
SELECT UserName, UPPER(FirstName) as FirstName, UPPER(LastName) as LastName
FROM PDDA.dbo.Users WHERE Cono = " & Cono & "
This is pretty easy.
var query1 = from u in Users where u.Cono == yourCono
select new { u.UserName, u.FirstName, u.LastName }
The second part is a little harder, but not much.
SELECT u.UserName, UPPER(FirstName) as FirstName, UPPER(LastName) as LastName
FROM PDDA.dbo.GroupMembers g
JOIN PDDA.dbo.UserGroups ug on ug.groupid = g.groupid
JOIN PDDA.dbo.Users u on u.username = g.username
WHERE ug.GroupName = 'AP Department' OR ug.GroupName = 'MIS'
ORDER BY LastName, FirstName
This would look something like this (not tested, but should be similar):
var query2 = from gm in GroupMembers
join ug in UserGroups on gm.groupid equals ug.groupid
join u in Users on gm.UserName equals u.UserName
where ug.GroupName == 'AP Department' || ug.GroupName == 'MIS'
orderby u.LastName, u.FirstName
select new { UserName = u.UserName, FirstName = u.FirstName, LastName = u.LastName }
Then just combine them.
var query3 = query1.Union(query2);
I'm not sure if the Order by orders the unioned set or not, if so, then you would just do this instead:
var query3 = query1.Union(query2).OrderBy(x => x.LastName).ThenBy(x => x.FirstName);
And you can remove the OrderBy from the query2 above.
EDIT:
Based on Striplings Query, you could probably even do this as well (assuming you have UserGroups navigation property configured):
from u in userDb.Users
where u.UserGroups.Any(ug => ug.GroupName == "AP Department" || ug.GroupName == "MIS")
|| u.Cono == yourCono
orderby u.LastName, u.FirstName
select new {u.UserName, u.FirstName, u.LastName}
No Union required at all then.
I find LINQ to be far more intuitive than SQL, and most people's difficulty with it arises from trying to do a direct translation rather than letting LINQ do the work for them. Assuming you've got your table relationships set up right, you can probably do something like this:
from u in userDb.Users
where u.UserGroups.Any(ug => ug.GroupName == "AP Department" || ug.GroupName == "MIS")
orderby u.LastName, u.FirstName
select new {u.UserName, u.FirstName, u.LastName};

How to use 'In' SQL keyword in Entity Framework?

This is my SQL command
SELECT KEY,NAME
from COMPANY c
WHERE KEY IN (select KEY from USER_COMPANY where UserId = #UserId)
order by NAME asc
So I want to convert it to Entity Framework.
I try like this
var userCompany = (from u in db.USER_COMPANY
where u.UserId == UserId
select(u.KEY));
var user = (from c in db.COMPANY
where (c => userCompany.Contains(c.KEY)
select c);
but it is not working.
How to use the SQL IN keyword in Entity Framework?
Try this:
var query = from c in db.COMPANY
where (from u in db.USER_COMPANY
where u.UserId == UserId
select u.KEY).Contains(c.KEY)
orderby c.NAME
select c.KEY, c.NAME;
Note that this SQL query has the exact same meaning:
SELECT c.KEY, c.NAME
FROM COMPANY c
JOIN (SELECT DISTINCT KEY FROM USER_COMPANY where UserId = #UserId) u
ON U.KEY = C.KEY
ORDER BY c.NAME asc
So you should be able to just do:
var userCompany = (from u in db.USER_COMPANY
where u.UserId == UserId
select(u.KEY)).Distinct();
var result = from c in db.COMPANY
join u in userCompany
on c.KEY = u.KEY
select new {c.KEY, c.NAME};
My understanding is that the translation from .Contains() to IN is only just being added to EF6.
According to this work item (http://entityframework.codeplex.com/workitem/245) and the release note: Improved performance of Enumerable.Contains in LINQ queries.
So look for it in EF6

Join two tables in Linq to SQL

Maybe a quite easy question but I'm new in Linq to SQL. I have two tables
User : UserId,name,Password,Email
USER_TABLE: Id, UserId, FirstName,LastName......
I would like a query that gives for example: userID=3 then give all the details (FirstName,LastName etc)
How can I join these two tables? I would prefer C# code if it is possible!
You do not have to do all the plumbing yourself. If you have the right foreign keys in the database you will not have to join yourself.
You can just do:
var query = from u in db.Users
select new { User = u;
FirstName = u.UserTables.FirstName }
for an inner join use something like:
var query = from u in db.Users
join ut in db.UserTables on u.UserId equals ut.UserId
select new
{
User = u,
Extra = ut
};
It's possible to join tables using linq:
E.g :
var test = (from a in DataContext.User
join b in DataContext.UserTable on a.UserId equals b.UserId
select new
{
UserId = a.UserId,
FirstName = b.FirstName
LastName = b.LastName
}).ToList();
Regards
Like this perhaps:
var joinedResult = from u in context.User
join u2 in context.UserTable on u.UserId equals u2.UserId
select new {
UserId = u.UserId,
FirstName = u2.FirstName
};
I guess your example is just an example, right? Cause it doesn't make much sense splitting that data into two tables.

Categories

Resources