I have this LINQ query and I need to make a second Join to it:
var linqQuery = (from r in gServiceContext.CreateQuery("opportunity")
join c in gServiceContext.CreateQuery("contact") on ((EntityReference)r["new_contact"]).Id equals c["contactid"] into opp
from o in opp.DefaultIfEmpty()
where ((EntityReference)r["new_channelpartner"]).Id.Equals(lProfileProperty.PropertyValue) && ((OptionSetValue)r["new_leadstatus"]).Equals("100000002")
select new
But I need to also Join this:
from r in gServiceContext.CreateQuery("annotation")
join c in gServiceContext.CreateQuery("opportunity") on ((EntityReference)r["objectid"]).Id equals c["opportunityid"]
Sorry, I'm sure this is easy. I suck at LINQ though. Any help would be great.
Thanks!
It's not really clear what you mean, but I suggest you want:
var linqQuery = from r in gServiceContext.CreateQuery("opportunity")
where ...
join c in gServiceContext.CreateQuery("contact")
on ((EntityReference)r["new_contact"]).Id
equals c["contactid"] into opp
from o in opp.DefaultIfEmpty()
join r in gServiceContext.CreateQuery("annotation")
on c["opportunityid"]
equals ((EntityReference)r["objectid"]).Id
select new...
It's not clear why you have to cast to EntityReference everywhere and access fields via their names as strings, by the way. Are you sure you can't use something like:
var linqQuery = from opportunity in gServiceContext.Opportunities
where opportunity.ChannelPartner.Id == targetChannelPartner
&& opportunity.NewLeadStatus == 100000002
join contact in gServiceContext.Contacts
on opportunity.Id equals contact.Id into contacts
from contactOrNull in contacts.DefaultIfEmpty()
join annotation in gServiceContext.Annotations
on annotation.ObjectId equals opportunity.OpportunityId
select ...;
Related
I need to convert a SQL query into LINQ, either to Query Syntax or Method Syntax.
SELECT
IA.ItemId,
IVT.ItemName,
C.DeliveryMethod,
SUM(OD.Quantity) AS Qty
FROM OrderHeader OH
INNER JOIN OrderDetail OD ON OH.OrderId = OD.OrderId
LEFT JOIN Customer C ON OH.CustomerId = C.Id
LEFT JOIN ItemAvailability IA ON OD.ItemId = IA.RecId
INNER JOIN Inventory IVT ON IA.ItemId = IVT.ItemId
WHERE OH.DeliveryDate = '02/03/2023'
AND OH.OrderType = 'Web'
GROUP BY IA.ItemId, Ivt.ItemName, C.DlvMode
ORDER BY IA.ItemId
I've spent a long time Googling and YouTubing, but everyone provides examples of either just Inner Joins, Group Joins, or Left Joins. No one gave example of having both Inner Joins and Left Joins in the same query.
I know the syntax for a simple inner join like this:
SQL
SELECT OH.OrderId, OD.ItemId, OD.Quantity
FROM OrderHeader OH
INNER JOIN OrderDetail OD ON OH.OrderId = OD.OrderId
ORDER BY OD.ItemId
LINQ
from oh in OrderHeader
join od in OrderDetail on oh.OrderId equals od.OrderId
orderby ordt.IItemId
select new {
OrderId = oh.OrderId,
ItemId = od.ItemId,
Quantity = od.Quantity
}
And I know the LINQ syntax for left join also. But I am having trouble to figure out how to have both inner and left joins in one LINQ query.
I hope someone here can help, please.
Just combine join techniques together
var deliveryDate = ...;
var query =
from oh in OrderHeader
join od in OrderDetail on oh.OrderId equals od.OrderId
join c in Customer ON oh.CustomerId equals c.Id into cj
from c in cj.DefaultIfEmpty()
join ia in ItemAvailability on od.ItemId equals ia.RecId into iaj
from ia in iaj.DefaultIfEmpty()
join ivt in Inventory on ia.ItemId equals ivt.ItemId
where oh.DeliveryDate == deliveryDate && oh.OrderType == "Web"
group od by new { ia.ItemId, ivt.ItemName, c.DlvMode, c.DeliveryMethod } into g
select new
{
g.Key.ItemId,
g.Key.DeliveryMethod,
Qty = g.Sum(x => x.Quantity)
} into s
orderby s.ItemId
select s;
I'm trying to build a linq query based on this:
select
SERVICE_REQUEST_CR.SRCR_FK_SR, SERVICE_REQUEST.SR_TX_NAME,
AC_USER.USER_TX_NAME, SERVICE_REQUEST_CR.SRCR_DT_CREATED,
SERVICE_REQUEST_CR_STATUS.SRCRST_TX_DESCRIPTION,
COUNT(SERVICE_REQUEST_PROGRAM.SRPG_FK_SR_ID) as Activities
from
SERVICE_REQUEST_CR
inner join
AC_USER on AC_USER.USER_ID = SERVICE_REQUEST_CR.SRCR_FK_REQUESTOR
inner join
SERVICE_REQUEST_CR_STATUS on SERVICE_REQUEST_CR_STATUS.SRCRST_ID = SERVICE_REQUEST_CR.SRCR_FK_CR_STATUS
inner join
SERVICE_REQUEST on SERVICE_REQUEST.SR_ID = SERVICE_REQUEST_CR.SRCR_FK_SR
inner join
SERVICE_REQUEST_PROGRAM on SERVICE_REQUEST_PROGRAM.SRPG_FK_SR_ID = SERVICE_REQUEST_CR.SRCR_FK_SR
group by
SERVICE_REQUEST_CR.SRCR_FK_SR, SERVICE_REQUEST.SR_TX_NAME,
AC_USER.USER_TX_NAME, SERVICE_REQUEST_CR.SRCR_DT_CREATED,
SERVICE_REQUEST_CR_STATUS.SRCRST_TX_DESCRIPTION,
SERVICE_REQUEST_PROGRAM.SRPG_FK_SR_ID
This is as far as I could come up with:
Dim x = From cr In db.SERVICE_REQUEST_CR
Join usr In db.AC_USER On usr.USER_ID Equals cr.SRCR_FK_REQUESTOR
Join crSt In db.SERVICE_REQUEST_CR_STATUS On crSt.SRCRST_ID Equals cr.SRCR_FK_CR_STATUS
Join sr In db.SERVICE_REQUEST On sr.SR_ID Equals cr.SRCR_FK_SR
Join srProg In db.SERVICE_REQUEST_PROGRAM On srProg.SRPG_FK_SR_ID Equals cr.SRCR_FK_SR
Could anyone give me a help with this? It's the grouping that gets confusing so I just put the joins and the query to keep it simple.
Thanks,
Something like this, but I am not sure about Basic syntax:
Dim x = From cr In db.SERVICE_REQUEST_CR
Join usr In db.AC_USER On usr.USER_ID Equals cr.SRCR_FK_REQUESTOR
Join crSt In db.SERVICE_REQUEST_CR_STATUS On crSt.SRCRST_ID Equals cr.SRCR_FK_CR_STATUS
Join sr In db.SERVICE_REQUEST On sr.SR_ID Equals cr.SRCR_FK_SR
Join srProg In db.SERVICE_REQUEST_PROGRAM On srProg.SRPG_FK_SR_ID Equals cr.SRCR_FK_SR
group new
{
cr.SRCR_FK_SR,
sr.SR_TX_NAME,
usr.USER_TX_NAME,
cr.SRCR_DT_CREATED,
crSt.SRCRST_TX_DESCRIPTION,
srProg.SRPG_FK_SR_ID
}
by new
{
cr.SRCR_FK_SR,
sr.SR_TX_NAME,
usr.USER_TX_NAME,
cr.SRCR_DT_CREATED,
crSt.SRCRST_TX_DESCRIPTION,
srProg.SRPG_FK_SR_ID
} into gr
select new
{
gr.Key.SRCR_FK_SR,
gr.Key.SR_TX_NAME,
gr.Key.USER_TX_NAME,
gr.Key.SRCR_DT_CREATED,
gr.Key.SRCRST_TX_DESCRIPTION,
gr.Key.SRPG_FK_SR_ID,
Activities = gr.Count()
}
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();
Here is my LINQ query with multiple joins:
it is working good but I need to do an enhancement in its working.
var selectedResults=
from InvoiceSet in Invoices
join BookedAreaSet in BookedAreas on InvoiceSet.InvoiceID equals BookedAreaSet.InvoiceID
join AreaSet in Areas on BookedAreaSet.AreaID equals AreaSet.AreaID
join ContactSet in Contacts on InvoiceSet.ContactID equals ContactSet.ContactID
join Contacts_ObjectsSet in Contacts_Objects on ContactSet.ContactID equals Contacts_ObjectsSet.ContactID
join CompanySet in Companies on Contacts_ObjectsSet.ObjectReferenceID equals CompanySet.CompanyID
join Customer_CustomerGroupSet in Customer_CustomerGroup on Contacts_ObjectsSet.ObjectReferenceID equals Customer_CustomerGroupSet.CustomerID
join CustomerGroupDiscountsSet in CustomerGroupDiscounts on Customer_CustomerGroupSet.CustomerGroupID equals CustomerGroupDiscountsSet.ID
join InvoiceStatusSet in InvoiceStatus on InvoiceSet.InvoiceStatusID equals InvoiceStatusSet.ID
where Contacts_ObjectsSet.ObjectReference=="Company"
//let minDate=(BookedAreaSet.LeasedDate).Min() where BookedAreaSet.InvoiceID=InvoiceSet.InvoiceID
select new {licensee=(CompanySet.CompanyName),CustomerGroupDiscountsSet.CustomerGroup,AreaSet.Location,InvoiceSet.InvoiceNumber,InvoiceSet.Amount,InvoiceSet.TotalDiscount,InvoiceSet.GST,
Paid=(InvoiceSet.InvoiceStatusID==2 ? "Paid":"UnPaid"),
datePaid=(InvoiceSet.PaymentDate),InvoiceSet.PaymentDate//,miDate
};
In query I have commented what I want to add as well as commented in Select. From BookedArea table I want to get Minimum Leased Date for every invoiceID.
I just have started using LINQ so dont know how to do this.
Please guide me.
Thanks
Try this:
var selectedResults=
from InvoiceSet in Invoices
join BookedAreaSet in BookedAreas on InvoiceSet.InvoiceID equals BookedAreaSet.InvoiceID
join AreaSet in Areas on BookedAreaSet.AreaID equals AreaSet.AreaID
join ContactSet in Contacts on InvoiceSet.ContactID equals ContactSet.ContactID
join Contacts_ObjectsSet in Contacts_Objects on ContactSet.ContactID equals Contacts_ObjectsSet.ContactID
join CompanySet in Companies on Contacts_ObjectsSet.ObjectReferenceID equals CompanySet.CompanyID
join Customer_CustomerGroupSet in Customer_CustomerGroup on Contacts_ObjectsSet.ObjectReferenceID equals Customer_CustomerGroupSet.CustomerID
join CustomerGroupDiscountsSet in CustomerGroupDiscounts on Customer_CustomerGroupSet.CustomerGroupID equals CustomerGroupDiscountsSet.ID
join InvoiceStatusSet in InvoiceStatus on InvoiceSet.InvoiceStatusID equals InvoiceStatusSet.ID
where Contacts_ObjectsSet.ObjectReference == "Company"
join BookedAreaSet2 in BookedAreas on InvoiceSet.InvoiceID equals BookedAreaSet.InvoiceID into BookedAreas2
let minDate = BookedAreas2.Select(ba2 => ba2.LeasedDate).Min()
select new
{
licensee = CompanySet.CompanyName,
CustomerGroupDiscountsSet.CustomerGroup,
AreaSet.Location,
InvoiceSet.InvoiceNumber,
InvoiceSet.Amount,
InvoiceSet.TotalDiscount,
InvoiceSet.GST,
Paid = InvoiceSet.InvoiceStatusID == 2 ? "Paid" : "UnPaid",
datePaid = InvoiceSet.PaymentDate,
InvoiceSet.PaymentDate,
minDate,
};
Is it possible to use LINQ to retrieve a list that may contain nulls.
For example if I have a left outer join like so:
var query= from c in db.Customers
join o in db.Orders
on c.CustomerID equals o.CustomerID into sr
from x in sr.DefaultIfEmpty()
select x.OrderId;
How do I get to a List that could look like {12,13,null,14,null,11,16,17}?
This doesn't work for me:
query.ToList<decimal?>();
Is it possible?
The problem is x.OrderId will throw a NullReferenceException when x is null. You need to check for null first, then return the property if there is an object. For example
select x == null ? (decimal?)null : x.OrderId;
OrderId doesn't quite sound like it ought to be a decimal though...
lc is correct, but it's a bit cleaner to simply cast your select to a nullable type outright.
var query= from c in db.Customers
join o in db.Orders
on c.CustomerID equals o.CustomerID into sr
from x in sr.DefaultIfEmpty()
select (decimal?)x.OrderId;
Try:
var query
= from c in db.Customers
join o in db.Orders
on c.CustomerID equals o.CustomerID into sr
select (sr != null : sr.OrderId : null);