linq where clause not in select statement - linq

Can someone help me to convert from SQL Query to LINQ VB.NET:
select rls.* from Roles rls(nolock)
where rls.id not in (
select r.ID from usersRole ur (nolock)
inner join Roles r(nolock) on ur.RoleID = r.ID
where user_id = 'NY1772')
Thanks

i find my own answer...
'construct a where ID list
Dim lstRoleIDs = From ur In ctx.UsersRoles _
Join rl In ctx.Roles _
On ur.RoleID Equals rl.ID _
Where ur.User_ID = UserId _
Select rl.ID
Dim newQ = (From r In ctx.Roles _
Where Not lstRoleIDs.Contains( _
r.ID) _
Select New UserRoleList With {.ID = r.ID, .PermDesc = r.ID & " - " & r.Permission & " - " & r.PermissionDescription})

If you want to preserve the (NOLOCK) hints, I have blogged a handy solution using extension methods in C#. Note that this is the same as adding nolock hints to every table in the query.

Related

Operation is not allowed when the object is closed (Object is not closed)

The following code, is generating that error.
Set getList = Server.CreateObject("ADODB.Command")
getList.ActiveConnection=EV_WikiConn
getList.Prepared = true
getList.commandtext= "declare #Lookup table(Id int identity(1, 1) , SongTitle nvarchar(512) )
insert into #Lookup(SongTitle)select * from ( values ('Deuce')) as x(a)
select A.AlbumName, S.SongTitle , S.Writers , S.Vocals , S.SID , S.TheTime
from Albums A inner join Songs S on A.AID = S.AID inner join #Lookup L on L.SongTitle = S.SongTitle order by L.Id"
set rsList = getList.execute
while not rsList.eof ' Error is on this line here.
I added this code here
Set getList = Server.CreateObject("ADODB.Command")
getList.ActiveConnection=EV_WikiConn
getList.Prepared = true
getList.commandtext= "declare #Lookup table(Id int identity(1, 1) , SongTitle nvarchar(512) )
insert into #Lookup(SongTitle)select * from ( values ('Deuce'),('Strutter'),('Parasite')) as x(a)
select A.AlbumName, S.SongTitle , S.Writers , S.Vocals , S.SID , S.TheTime
from Albums A inner join Songs S on A.AID = S.AID inner join #Lookup L on L.SongTitle = S.SongTitle order by L.Id"
set rsList = getList.execute
If rsList.State <> adStateOpen Then
While rsList.State <> adStateOpen
Set rsList = rsList.NextRecordset
rsList.movenext
wend
end if
This makes it run, however, I only get one record, instead of the 10 that is in the actual form. So, this is not going to work, but wanted to show what I have tried so far.
OK, got it all figured out. below is the code that was used, with a few notes in the code, to show what I did to make it work.
Set getList = Server.CreateObject("ADODB.Command")
getList.ActiveConnection=EV_WikiConn
getList.Prepared = true
getList.commandtext = _
"SET NOCOUNT ON " & _
"declare #Lookup table(Id int identity(1, 1) , " & _
"SongTitle nvarchar(512) ) " & _
"insert into #Lookup(SongTitle)select * from " & _
"( values ('Hotter_Than_Hell'), ('Firehouse'), ('She'), " & _
"('Parasite'), ('Nothin''_To_Lose')) as x(a) " & _
"select A.AlbumName, S.SongTitle , S.Writers , S.Vocals , " & _
"S.SID , S.TheTime from Albums A inner join " & _
"Songs S on A.AID = S.AID inner join " & _
"#Lookup L on L.SongTitle = S.SongTitle order by L.Id"
' the SET NOCOUNT ON, was added, but did not resolve the issue, I just left it in.
' The next 3 lines is what fixed the issue.
While rsList.State <> adStateOpen
Set rsList = rsList.NextRecordset
Wend
While Not rsList.EOF%>
<%=rsList("SongTitle")%>
<%rsList.movenext
wend
rsList.Close
set rsList = nothing
Regardless of what the OP believes this is a duplicate of
ADODB.Recordset error '800a0e78' Operation is not allowed when the object is closed
If we analyse the original code revision (ignoring the hard wrap which will cause an error in VBScript)
Set getList = Server.CreateObject("ADODB.Command")
getList.ActiveConnection=EV_WikiConn
getList.Prepared = true
getList.commandtext= "declare #Lookup table(Id int identity(1, 1) , SongTitle nvarchar(512) )
insert into #Lookup(SongTitle)select * from ( values ('Deuce')) as x(a)
select A.AlbumName, S.SongTitle , S.Writers , S.Vocals , S.SID , S.TheTime
from Albums A inner join Songs S on A.AID = S.AID inner join #Lookup L on L.SongTitle = S.SongTitle order by L.Id"
set rsList = getList.execute
while not rsList.eof ' Error is on this line here.
You can see that the original issue is the lack of
SET NOCOUNT ON;
to stop the closed ADODB.Recordset object being returned for the initial INSERT operation.
The subsequent edits the OP makes confuses the issue, before this adding SET NOCOUNT ON; would have fix the problem without needing further changes.
The next revision is where the confusion begins (again, ignoring the hard wrap which will cause an error in VBScript)
Set getList = Server.CreateObject("ADODB.Command")
getList.ActiveConnection=EV_WikiConn
getList.Prepared = true
getList.commandtext= "declare #Lookup table(Id int identity(1, 1) , SongTitle nvarchar(512) )
insert into #Lookup(SongTitle)select * from ( values ('Deuce'),('Strutter'),('Parasite')) as x(a)
select A.AlbumName, S.SongTitle , S.Writers , S.Vocals , S.SID , S.TheTime
from Albums A inner join Songs S on A.AID = S.AID inner join #Lookup L on L.SongTitle = S.SongTitle order by L.Id"
set rsList = getList.execute
If rsList.State <> adStateOpen Then
While rsList.State <> adStateOpen
Set rsList = rsList.NextRecordset
rsList.movenext
wend
end if
Let's just dissect this part
If rsList.State <> adStateOpen Then
While rsList.State <> adStateOpen
Set rsList = rsList.NextRecordset
rsList.movenext
wend
end if
First the If and While loop do the same thing accept the While does it repeatedly until the condition is met, making the If completely irrelevant.
The While loop checks for the current state of the ADODB.Recordset which without SET NOCOUNT ON; is returned as adStateClosed (due to the INSERT operation). This is fine but by changing the While loop from
while not rsList.eof
to
While rsList.State <> adStateOpen
the condition has been changed and the While is no longer checking for rsList.EOF which would be the case when we are enumerating the ADODB.Recordset object. However, now it is only checking for the .State of rsList which once .NextRecordset is called will exit the loop as a open ADODB.Recordset object has been returned. Because the condition has been met the loop will only run once calling .MoveNext once and only returning one record.
So to summaries using
SET NOCOUNT ON;
initially would have negated this whole scenario but hey "I don't understand the code" apparently.

How to execute Datatable Linq Union

I have a datatable that contains below data.
Table 1
880000000010747
880000000012235
880000000000010
880000000015086
880000000000028
Table 2
880000000014718
880000000014928
880000000009684
880000000013184
880000000010747
How can i union the tables and return the result below?
880000000010747
880000000012235
880000000000010
880000000015086
880000000000028
880000000014718
880000000014928
880000000009684
880000000013184
From .Net 3.5 to 4.5 (at time on writing) you can use the Union method
http://msdn.microsoft.com/en-us/library/bb386993(v=vs.110).aspx
C# Example:
var infoQuery =
(from cust in db.Customers
select cust.Country)
.Union
(from emp in db.Employees
select emp.Country)
;
VB.net Example:
Dim infoQuery = _
(From cust In db.Customers _
Select cust.Country) _
.Union _
(From emp In db.Employees _
Select emp.Country)
If you to join all regardless of duplicates check out the Concat Method:
http://code.msdn.microsoft.com/LINQ-Miscellaneous-6b72bb2a#Concat1
Hope that helps.

What is a good strategy for handling Complex Right Outer Joins in LINQ / EF

I have this Model
My goal is to retrieve all resources for a user except for resources that share a restricted role with that user.
This is not too hard in straight SQL (6BA60C09-2873-46A5-BAFB-5996A6C6482B is the userid)
SELECT distinct r.Name
FROM dbo.Resources xr
INNER JOIN [dbo].[x_Resource_RestrictedRole] rr ON xr.Id = rr.ResourceId
INNER JOIN [dbo].[aspnet_UsersInRoles] ur ON ur.RoleId = rr.RoleId
AND ur.UserId = '6BA60C09-2873-46A5-BAFB-5996A6C6482B'
RIGHT JOIN dbo.Resources r on r.id = xr.id
WHERE xr.id IS NULL
I can't figure out a good strategy for this in EF because I don't have access to the association tables.
Can this be done in LINQ or lambda expression?
You have some sort of question but I will try to answer about your query
var y = (from xr in context.Resources
join rr in context.x_Resource_RestrictedRole on xr.Id equals rr.ResourceId
join ur in context.aspnet_UsersInRoles on rr.RoleId equals ur.RoleId
join r in context.Resources on xr.id equals r.id into rJoin
from r2 in rJoin.DefaultIfEmpty()
where xr.id == null && ur.UserId = "6BA60C09-2873-46A5-BAFB-5996A6C6482B"
select new { r.Name }).Distinct(c => c.Name).ToList();

linq to sql using foreign keys returning iqueryable(of myEntity]

I'm trying to use Linq to SQL to return an IQueryable(of Project) when using foreign key relationships. Using the below schema, I want to be able to pass in a UserId and get all the projects created for the company the user is associated with.
DB tables:
Projects
Projid
ProjCreator FK (UserId from UserInfo table)
Companyid FK (CompanyID from Companies table)
UserInfo
UserID PK
Companyid FK
Companies
CompanyId PK
Description
I can get the iqueryable(of project) when simply getting the ProjectCreator with this:
Return (From p In db.Projects _
Where p.ProjectCreator = Me.UserId)
But I'm having trouble getting the syntax to get a iqueryable(of projects) when using foreign keys. Below gives me an IQueryable(of anonymous) but I can't seem to convince it to give me an IQueryable(of project) even if I try to cast it:
Dim retval = (From p In db.Projects _
Join c In db.Companies On p.CompanyId Equals c.CompanyId _
Join u In db.UserInfos On u.CompanyId Equals c.CompanyId _
Where u.Login = UserId)
Simply select the project:
Dim retval = (From p In db.Projects _
Join c In db.Companies On p.CompanyId Equals c.CompanyId _
Join u In db.UserInfos On u.CompanyId Equals c.CompanyId _
Where u.Login = UserId _
Select p)

LINQ multiple condition on "on" clause

I have a query which have multiple conditions on on clause
SELECT *
FROM
CATALOGITEM with (nolock) INNER JOIN CATALOG with (nolock) ON
CATALOGITEM.catalog_id = CATALOG.catalog_id and not(catalog.catalog_id = 21) AND NOT(catalog.catalog_id = 20)
INNER JOIN PRODUCT with (nolock) ON
CATALOGITEM.s_num = PRODUCT .s_num
LEFT OUTER JOIN PRODUCT_DETAIL with (nolock) ON
PRODUCT_DETAIL.s_num = PRODUCT.s_num
WHERE
(
CATALOGITEM.publish_code = 'upd' OR
CATALOG_ITEM.publish_code = 'ins' OR
PRODUCT.publish_code = 'upd' OR
PRODUCT.publish_code = 'ins'
)
and
(CATALOG.unit_id = bu.unit_id)
How to write this in LINQ.
Please advice.
Assume you're missing a join to PRODUCT table?
Anyway, this should get you started.
var query = (from ci in db.catalogitem
join c in db.catalog on ci.catalog_id equals c.catalog_id
join p in db.products on ci.s_num equals p.s_num
join pd in db.productdetail on p.s_num equals pd.s_num into tempprods
from prods in tempprods.DefaultIfEmpty()
where !(c.catalog_id.Contains(21, 20))
&& (ci.publish_code.Contains('upd','ins')) ||
(p.publish_code.Contains('upd','ins'))
select ci)
If you want to preserve the (NOLOCK) hints, I have blogged a handy solution using extension methods in C#. Note that this is the same as adding nolock hints to every table in the query.

Resources