How to write lambda (linq) expression for sql? - linq

I have an Sql statement for which I need go generate corresponding Lambda Expression (Linq).
Here is the SQL
Declare #CurrentUserId as int
Declare #CurrentDate as datetime
Set #CurrentDate = GetDate()
Set #CurrentUserId = 1
Select C.conferenceId,C.specialtyId,C.name,C.city,S.abbr as statebbbr,CTRY.name as countryname,C.startdate,C.enddate
from Conferences C
Inner join (
Select distinct SpecialtyId
from UserContent
Where UserId = #CurrentUserId and DeletedFlag = 0
) DT on C.SpecialtyId = DT.SpecialtyId
Left outer join State S on C.StateId = S.StateId
Inner join Country CTRY on C.CountryId = CTRY.CountryId
Where C.DisplayStartDate <= #CurrentDate
and C.DisplayEndDate >= #CurrentDate
and C.DeletedFlag = 0
and C.Publish = 1
Order by C.startdate ASC
What wolud be the lambda(linq) expression for this?

Assume data context is in variable context
from c in context.conferences
join ctry in context.country on c.CountryId equals ctry.CountryId
join s1 in context.State on c.StateId equals s.StateId into s2
from s in s2.DefaultIfEmpty()
where
c.DisplayStartDate <= System.DateTime.Now
&& c.DisplayEndDate >= System.DateTime.Now
&& c.DeletedFlag == 0 // or false if represented as a bool
&& c.Publish == 1 // or true if represented as a bool
&& context.UserContent.Any(
x => x.SpecialityId == c.specialityId
&& x.UserId == currentUserId
&& x.DeletedFlag == 0
// or if represented as a bool "&& !x.DeletedFlag"
)
select new {
c.ConferenceId,
c.SpecialtyId,
c.name,
c.city,
stateabbr = s.abbr,
countryname = ctry.name,
c.startdate,
c.enddate
}

Related

Using subquery in entity framework

I am trying to write the entity framework linq query to generate the following SQL. But I am not sure how to use subqueries with entity framework.
The Sql I want to generate is:
Declare #StartDate Datetime2; Set #Startdate = '2014-Feb-16 09:52'
Declare #EndDate Datetime2; Set #Enddate = '2014-Feb-18 09:52'
SELECT
[D].[RefId]
,[D].[StatusId]
,[D].[StatusDate]
,[D].[Reference]
,[RSC].[Event]
,[RSC].[Information]
,[RSC].[CreatedDate]
FROM (
SELECT
[R].[RefId]
,[R].[StatusId]
,[R].[StatusDate]
,[I].[Reference]
,(SELECT TOP 1
[RSC].[ChangeId]
FROM
[dbo].[StateChangeTable] AS [RSC] (nolock)
WHERE
[RSC].[RefId] = [R].[RefId]
ORDER BY
[RSC].[ChangeId] DESC) AS [LastChangeId]
FROM
[dbo].[Table1] AS [R] (nolock)
INNER JOIN
[dbo].[Table2] AS [I] (nolock)
ON
[R].[RefId] = [I].[RefId]
WHERE
[R].[StatusId] IN (4, 6)
AND [R].[StatusDate] between #StartDate and #EndDate
) AS [D]
INNER JOIN
[dbo].[StateChangeTable] AS [RSC] (nolock)
ON
[D].[LastChangeId] = [RSC].[ChangeId
]
And the code I wrote till now is:
return this.DbContext.Table1
.Join(this.DbContext.Table2, rc => rc.RefId, ri => ri.RefId, (rc, ri) => new { rc, ri })
.Join(this.DbContext.StateChangeTable, request => request.ri.RefId, rsc => rsc.RefId, (request, rsc) => new {request, rsc})
.Where(r => (r.rsc.ChangeId == ((from rsc in this.DbContext.StateChangeTable
orderby rsc.ChangeId descending
select rsc.ChangeId).FirstOrDefault())) &&
(r.request.rc.StatusId == 4 || r.request.rc.StatusId == 6) &&
(r.request.rc.StatusDate >= startDateTime && r.request.rc.StatusDate <= endDateTime))
.Select(requestDetails => new StatusDetail
{
RefId = requestDetails.request.rc.RefId,
StatusDate = requestDetails.request.rc.StatusDate,
StatusId = requestDetails.request.rc.StatusId,
Reference = requestDetails.request.ri.DistributionReference.Value,
Event = requestDetails.rsc.Event,
CreatedDate = requestDetails.rsc.CreatedDate,
Information = requestDetails.rsc.Information
}).ToList();
Can some please let me know what I am doing wrong?
Many Thanks
Here is the Full query
var query = (from D in
((from tab1 in DbContext.Table1
join tab2 in DbContext.Table2 on tab1.RefId equals tab2.RefId
where (tab1.StatusId == 4 || tab1.StatusId == 6)
&& (tab1.StatusDate >= startDate && tab1.StatusDate <= endDate)
select new
{
RefId = tab1.RefId,
StatusId = tab1.StatusId,
StatusDate = tab1.StatusDate,
Reference = tab2.Reference,
LastChangeId = (from RSC in DbContext.StateChangeTable
where RSC.RefId == tab1.RefId
orderby RSC.ChangeId descending
select RSC.ChangeId).FirstOrDefault()
}))
join RSC in DbContext.StateChangeTable on D.LastChangeId equals RSC.ChangeId
select new StatusDetail
{
RefId = D.RefId,
StatusId = D.StatusId,
StatusDate = D.StatusDate,
Reference = D.Reference,
Event = RSC.Event,
Information = RSC.Information,
CreatedDate = RSC.CreatedDate
}).ToList();
Don't use .Join() you have to use the navigation properties on your entities.

How to convert exists condition inside where clause in Linq

I want to add following where clause to Linq query. How subquery like below using linq
WHERE (Restaurants.[IsActive] = 1)
AND exists
(
select 1 from APIKeys
where ApiKey = 'on35e5xbt3m4cbcef4e4448t6wssg11o'
and (KeyType = 1
and fk_RestaurantsID = [t2].[RestaurantsID]
or KeyType = 2
and fk_RestaurantGroupID = RG.RestaurantGroupsID
and [t1].[fk_RestaurantsID] in
(SELECT RestaurantsID
FROM Restaurants
WHERE RestaurantGroupsID = RG.RestaurantGroupsID))
)
AND (0 = (COALESCE([t0].[fk_MembersID],0)))
AND (1 = [t0].[fk_BookingStatusID])
AND ([t0].[Email] = 'nike.s#gmail.com')
AND (([t0].[Phone] = '9999999990') OR ([t0].[MobilePhone] = '9999999990'))
Use Any() to produce subquery which translated to EXISTS. E.g. with AdventureWorks database sample:
from p in Products
where p.FinishedGoodsFlag &&
SalesOrderDetails.Any(od => od.ProductID == p.ProductID)
select new { p.ProductID, p.Name }
Will produce following query to database:
SELECT [t0].[ProductID], [t0].[Name]
FROM [Production].[Product] AS [t0]
WHERE ([t0].[FinishedGoodsFlag] = 1) AND (EXISTS(
SELECT NULL AS [EMPTY]
FROM [Sales].[SalesOrderDetail] AS [t1]
WHERE [t1].[ProductID] = [t0].[ProductID]
))

Any vs Where clause in LINQ

I always thought LINQ to SQL equivalent for an exists query is to use Any(). But i recently wrote a query in LINQ , which basically is trying to find if duplicate records exists in single table.
Anycontext.Contacts.Any(c => ((c.FirstName == contact.FirstName && c.LastName == contact.LastName && c.AddressLine1 == contact.AddressLine1 && c.Zip == contact.Zip)||
(!String.IsNullOrEmpty(contact.Email) && c.Email == contact.Email)))
matching criteria is simple to find contacts with same FirstName, LastName and AddressLine1 or same Email. This query times out in 30 sec(default), there are just 500K rows in this table.
Wherecontext.Contacts.Where(c => ((c.FirstName == contact.FirstName && c.LastName == contact.LastName && c.AddressLine1 == contact.AddressLine1 && c.Zip == contact.Zip)||
(!String.IsNullOrEmpty(contact.Email) && c.Email == contact.Email))).Count()>0
I was forced to use Where clause and then do count greater than 0 to find if any duplicate exists in the set. What i can not understand is, why LINQ to SQL on simple Any clause timing out.
Any explanation will be really great here.
EDIT
SQL From from LINQ Pad
ANY
SELECT
(CASE
WHEN EXISTS(
SELECT NULL AS [EMPTY]
FROM [Accounts].[Contacts] AS [t0]
WHERE ([t0].[CompanyID] = #p0) AND ((([t0].[FirstName] = #p1) AND ([t0].[LastName] = #p2) AND ([t0].[AddressLine1] = #p3) AND ([t0].[Zip] = #p4)) OR (([t0].[FirstName] = #p5) AND ([t0].[LastName] = #p6) AND (EXISTS(
SELECT NULL AS [EMPTY]
FROM [Accounts].[PhoneNumbers] AS [t1]
WHERE ([t1].[ContactNumber] = #p7) AND ([t1].[ContactID] = [t0].[ContactID])
))))
) THEN 1
ELSE 0
END) AS [value]
Where
SELECT [t0].[ContactID]
,[t0].[CompanyID]
,[t0].[CompanyTitle]
,[t0].[FirstName]
,[t0].[LastName]
,[t0].[AddressLine1]
,[t0].[AddressLine2]
,[t0].[City]
,[t0].[State]
,[t0].[Zip]
,[t0].[Email]
,[t0].[Salutation]
,[t0].[IsActive]
FROM [Accounts].[Contacts] AS [t0]
WHERE ([t0].[CompanyID] = #p0)
AND (
(
([t0].[FirstName] = #p1)
AND ([t0].[LastName] = #p2)
AND ([t0].[AddressLine1] = #p3)
AND ([t0].[Zip] = #p4)
)
OR (
([t0].[FirstName] = #p5)
AND ([t0].[LastName] = #p6)
AND (
EXISTS (
SELECT NULL AS [EMPTY]
FROM [Accounts].[PhoneNumbers] AS [t1]
WHERE ([t1].[ContactNumber] = #p7)
AND ([t1].[ContactID] = [t0].[ContactID])
)
)
)
)
Not completely sure if this is what you want, but you could compare, I'm guessing you wont run the test often, as it would be better to test for existence before you input the data to the DB.
If you want to find the duplicates then
var queryA = from a in db.someTable
select a.value;
foreach(var row in queryA){
Console.Write(queryA.Where(b => b == row).Count() > 1 ? row: "");
}
If you just want to test if it exist then.
var queryA = from a in db.someTable
select a.value;
var queryB = queryA;
queryB.Distinct();
Console.Write(queryB.Count() != queryA.Count() ? "Yes" : "No");

Subselect with LINQ

I want to do a subselect with LINQ
What I have, but incorrect
var diretores = from item in db.San_PropostaConversa
join sc in db.San_Credenciada
on (item.Credenciada_Id) equals sc.Credenciada_Id
join sp in db.San_Proposta
on (item.Proposta_Id) equals sp.Proposta_Id
join si in db.San_Imovel
on (sp.Imovel_Id) equals si.Imovel_Id
join su in db.San_Usuario
on (item.Usuario_Id) equals su.Usuario_Id
where item.Proposta_Id == proposta
orderby item.DataHora descending
select new
{
sc.Apelido,
su.NomeCompleto,
su.DescricaoCargo1,
item.Comentario,
item.DataHora,
sp.Imovel_Id,
CredenciadaCaptadora_Id = si.Credenciada_Id,
item.Credenciada_Id,
(from item2 in db.San_Usuario
where item2.Cargo_Id == 9
&& item2.Excluido == 0
&& item2.Credenciada_Id == item.Credenciada_Id
select item2.Email)
};
In my SELECT statement, I want to recover an email column following some conditions that are specified in my WHERE clause.
Error
Invalid anonymous type member declarator. Anonymous type members must
be declared with a member assignment, simple name or member access
You have 2 problems in your linq expression:
You need to assign the result of the subquery to a member of the new anonymous type.
I think you only want to select 1 email with your subquery, so you need to use Single()/SingleOrDefault() or First()/FirstOrDefault().
Try this:
var diretores = from item in db.San_PropostaConversa
join sc in db.San_Credenciada
on item.Credenciada_Id equals sc.Credenciada_Id
join sp in db.San_Proposta
on (item.Proposta_Id) equals sp.Proposta_Id
join si in db.San_Imovel
on sp.Imovel_Id equals si.Imovel_Id
join su in db.San_Usuario
on item.Usuario_Id equals su.Usuario_Id
where item.Proposta_Id == proposta
orderby item.DataHora descending
select new
{
Apelido = sc.Apelido,
NomeCompleto = su.NomeCompleto,
DescricaoCargo1 = su.DescricaoCargo1,
Comentario = item.Comentario,
DataHora = item.DataHora,
Imovel_Id = sp.Imovel_Id,
CredenciadaCaptadora_Id = si.Credenciada_Id,
Credenciada_Id = item.Credenciada_Id,
Email = (from item2 in db.San_Usuario
where item2.Cargo_Id == 9
&& item2.Excluido == 0
&& item2.Credenciada_Id == item.Credenciada_Id
select item2.Email).FirstOrDefault()
};
Mostly this error occurring for unavailable assigning variable,
please try this
it will help you
var diretores = from item in db.San_PropostaConversa
join sc in db.San_Credenciada
on (item.Credenciada_Id) equals sc.Credenciada_Id
join sp in db.San_Proposta
on (item.Proposta_Id) equals sp.Proposta_Id
join si in db.San_Imovel
on (sp.Imovel_Id) equals si.Imovel_Id
join su in db.San_Usuario
on (item.Usuario_Id) equals su.Usuario_Id
where item.Proposta_Id == proposta
orderby item.DataHora descending
select new
{
Apelido=sc.Apelido,
NomeCompleto=su.NomeCompleto,
DescricaoCargo1=su.DescricaoCargo1,
Comentario=item.Comentario,
DataHora=item.DataHora,
Imovel_Id=sp.Imovel_Id,
CredenciadaCaptadora_Id = si.Credenciada_Id,
Credenciada_Id= item.Credenciada_Id,
result= (from item2 in db.San_Usuario
where item2.Cargo_Id == 9
&& item2.Excluido == 0
&& item2.Credenciada_Id == item.Credenciada_Id
select item2.Email)
};

Sql to linq convention

i have a problem to build my linq query and i need you help , the following code is what i have got so far
, it does has some errors as expected, so, this is my sql query :
*im new to linq and did searched over google.
select CAST(h.changedate as date) as 'RegDate' ,count (cast(h.changedate as date)) as 'Amount' from T_TalmidStatusHistory h
join T_talmid t on h.talmidid = t.talmidid
where t.talmidStatusID=16 and h.[statusid] != 16
and h.id =
(
select max(id) from T_TalmidStatusHistory
where T_TalmidStatusHistory.talmidid=h.talmidid and T_TalmidStatusHistory.[statusid] != 16
)
group by CAST(h.changedate as date)
and this is what i have right now in linq:
var res = from r in db.T_TalmidStatusHistories
from m in db.T_TalmidStatusHistories
join t in db.T_Talmids on r.TalmidID equals t.TalmidID
where t.TalmidStatusID == 16 && r.StatusID != 16
&& r.id == from l in db.T_TalmidStatusHistories
where m.TalmidID == r.TalmidID && m.StatusID != 16
select new{db.T_TalmidStatusHistories.OrderByDescending(tp => tp.id).FirstOrDefault().id }
group h by h.changedate as date
select new { h.changedate as date, count (cast(h.changedate as date))};
Edit:
i'm expecting to get the number of students that sign up on each date,
my error is :
Operator '==' cannot be applied to operands of type 'int' and 'System.Linq.IQueryable'
at line : r.id == from l in db.T_TalmidStatusHistories
ty.
The whole part
from l in db.T_TalmidStatusHistories ... count (cast(h.changedate as date))}
is one query which is compared to r.id by the == operator.
Change it to
...
r.id == (db.T_TalmidStatusHistories
.Where(m.TalmidID == r.TalmidID && m.StatusID != 16)
.OrderByDescending(tp => tp.id).FirstOrDefault().id)
group h by h.changedate as date
select new { h.changedate as date, count (cast(h.changedate as date))};

Resources