I am working on asp.net core application. I have following linq query which is being used to fill a model. This model has a property qtryregions which is a list. How can I fill it in one query.
public JsonResult PODetailsList(int id)
{
List<PODetailsFull> Products;
Products =
(from d in db.PODetails
join p in db.Products on d.ProductID equals p.ProductID
where d.POID == id
select new PODetailsFull
{
PODetailID = d.PODetailID,
//QtyRegion = new List<string>() { Region.Region + " " + POAllocation.Allocate != null ? POAllocation.Allocate.ToString() : "" },
Sku = p.Sku,
Cntnr20 = p.Cntnr20 ?? 0,
Cntnr40 = p.Cntnr40 ?? 0,
Cntnr40HQ = p.Cntnr40HQ ?? 0,
}).ToList();
foreach (var product in Products)
{
var result = (from POAllocation in db.POAllocations.Where(p => p.PODetailID == product.PODetailID)
join regions in db.Regions on POAllocation.RegionID equals regions.RegionID
select regions.Region + " " + POAllocation.Allocate ?? ""
).ToList();
product.QtyRegion = result;
}
return Json(new { data = Products }, JsonRequestBehavior.AllowGet);
}
I don't want to use above foreach and want to populate product.Qtyregion in first linq query.
Please suggest.
Is this what you want?
Products = (
from d in db.PODetails
join p in db.Products on d.ProductID equals p.ProductID
where d.POID == id
select new PODetailsFull
{
PODetailID = d.PODetailID,
//QtyRegion = new List<string>() { Region.Region + " " + POAllocation.Allocate != null ? POAllocation.Allocate.ToString() : "" },
Sku = p.Sku,
Cntnr20 = p.Cntnr20 ?? 0,
Cntnr40 = p.Cntnr40 ?? 0,
Cntnr40HQ = p.Cntnr40HQ ?? 0,
QtyRegion = (
from POAllocation in db.POAllocations.Where(p => p.PODetailID == d.PODetailID)
join regions in db.Regions on POAllocation.RegionID equals regions.RegionID
select regions.Region + " " + POAllocation.Allocate ?? "").ToList(),
}).ToList();
Try to use Group By to avoid N+1 queries issue:
Products = (
from d in db.PODetails
join p in db.Products on d.ProductID equals p.ProductID
join palloc in db.POAllocations on d.PODetailID equals palloc.PODetailID
group by new {
PODetailID = d.PODetailID,
Sku = p.Sku,
Cntnr20 = p.Cntnr20,
Cntnr40 = p.Cntnr40,
Cntnr40HQ = p.Cntnr40HQ }
into grp
where grp.Key.POID == id
select new PODetailsFull
{
PODetailID = grp.Key.PODetailID,
QtyRegion = grp,
Sku = grp.Key.Sku,
Cntnr20 = grp.Key.Cntnr20 ?? 0,
Cntnr40 = grp.Key.Cntnr40 ?? 0,
Cntnr40HQ = grp.Key.Cntnr40HQ ?? 0
}).ToList();
Related
I have list table with 2 record. List A and List B. List A has 4 tasks in Task table and List B has 2 tasks in Task table. Task 1 of List A has two time log entries in TimeLog table.No foreign key used.
Now Consider the following code.
var objs = from project_task_list in modelRepository.Get()
join project_task in projectTaskRepository.Get() on project_task_list.ListId equals project_task.ListId into project_task_result
join project_task_timelog in projectTaskTimeLogRepository.Get() on project_task.TaskId equals project_task_timelog.TaskId into project_task_timelog_result
where project_task_list.ProjectId == project_id
select new ProjectTaskListModel
{
ListId = project_task_list.ListId,
ProjectId = project_task_list.ProjectId ?? 0,
ListName = project_task_list.ListName,
ListStartDate = project_task_list.ListStartDate,
ListEndDate = project_task_list.ListEndDate,
ListStatusId = project_task_list.ListStatusId ?? 0,
ListSortOrder = project_task_list.ListSortOrder ?? 0,
ListTasksEstimatedHours = project_task_result.Sum(x => x.TaskEstimatedHours) ?? 0,
ListTasksTimeLogTotalMinutes = project_task_timelog_result.Sum(x => x.LogMinutes) ?? 0
};
I want to use result of one join in another join but i am having following syntax error.
I have also tried the following code.
var objs = from project_task_list in modelRepository.Get()
join project_task in projectTaskRepository.Get() on project_task_list.ListId equals project_task.ListId into project_task_result
from project_task in project_task_result.DefaultIfEmpty()
join project_task_timelog in projectTaskTimeLogRepository.Get() on project_task.TaskId equals project_task_timelog.TaskId into project_task_timelog_result
where project_task_list.ProjectId == project_id
select new ProjectTaskListModel
{
ListId = project_task_list.ListId,
ProjectId = project_task_list.ProjectId ?? 0,
ListName = project_task_list.ListName,
ListStartDate = project_task_list.ListStartDate,
ListEndDate = project_task_list.ListEndDate,
ListStatusId = project_task_list.ListStatusId ?? 0,
ListSortOrder = project_task_list.ListSortOrder ?? 0,
ListTasksEstimatedHours = project_task_result.Sum(x => x.TaskEstimatedHours) ?? 0,
ListTasksTimeLogTotalMinutes = project_task_timelog_result.Sum(x => x.LogMinutes) ?? 0
};
Syntax error gone but the problem is it is returning 6 records while i only have 2 records in list table. What am i doing wrong? Thanks in advance.
I have figured it out my self. All i need was GROUP BY clause in LINQ. Here is the final query.
var objs = from project_task_list in modelRepository.Get()
join project_task in projectTaskRepository.Get() on project_task_list.ListId equals project_task.ListId into project_task_result
from project_task in project_task_result.DefaultIfEmpty()
join project_task_timelog in projectTaskTimeLogRepository.Get() on project_task.TaskId equals project_task_timelog.TaskId into project_task_timelog_result
from project_task_timelog in project_task_timelog_result.DefaultIfEmpty()
where project_task_list.ProjectId == project_id
group new { project_task_list, project_task, project_task_timelog } by new
{
project_task_list.ListId,
project_task_list.ProjectId,
project_task_list.ListName,
project_task_list.ListStartDate,
project_task_list.ListEndDate,
project_task_list.ListStatusId,
project_task_list.ListSortOrder
} into group_result
select new ProjectTaskListModel
{
ListId = group_result.Key.ListId,
ProjectId = group_result.Key.ProjectId ?? 0,
ListName = group_result.Key.ListName,
ListStartDate = group_result.Key.ListStartDate,
ListEndDate = group_result.Key.ListEndDate,
ListStatusId = group_result.Key.ListStatusId ?? 0,
ListSortOrder = group_result.Key.ListSortOrder ?? 0,
ListTasksEstimatedHours = group_result.Sum(x => x.project_task.TaskEstimatedHours) ?? 0,
ListTasksTimeLogTotalMinutes = group_result.Sum(x => x.project_task_timelog.LogMinutes) ?? 0
};
So I had an issue yesterday that I worked through and increased the speed of my program, but I'm having an issue where I never hit the return breakpoint nor an exception. This query can run multiple times at once depending on the schedualed times it needs to run, but does work if I run it solo with one company. Any idea why?
try
{
//work on query further , need to get client ID correctly
if (vehicleses.Count == 0)
return null;
string siteId = QueryExportSiteWithId(exportSiteId).SiteId;
string clientId = vehicleses[0].ClientID;
var inventoryyReturn = from i in db.Inventory_Vehicles
where dealerIdList.Any(c => c == i.ClientID) && i.Archived != "1" && i.Holding != "1" &&
i.Status == "A"
select i;
var inventoryDescription = from i in db.Inventory_Descriptions
where
inventoryyReturn.Any(
c => new {client = c.ClientID, inv = c.ID} == new {client = i.ClientID, inv = i.InventoryID})
select i;
var settingsExports = from i in db.Settings_Exports
where inventoryyReturn.Any(c => c.ClientID == i.ClientID)
select i;
var settingLots = from i in db.Settings_Lots
where
inventoryyReturn.Any(
c => new {client = c.ClientID, lot = c.LotID} == new {client = i.ClientID, lot = i.ID})
select i;
var inventoryFeatures = from i in db.Inventory_Features
where
inventoryyReturn.Any(
c => new {client = c.ClientID, inv = c.ID} == new {client = i.ClientID, inv = i.InventoryID})
select i;
var inventoryPhotos = from i in db.Inventory_Photos
where
inventoryyReturn.Any(c => c.ID == i.InventoryID)
select i;
var longReturnListt = await (from i in inventoryyReturn
join l in inventoryDescription on new {inv = i.ID, cli = i.ClientID} equals
new {inv = l.InventoryID, cli = l.ClientID} into descGroup
from m in descGroup.DefaultIfEmpty()
join s in settingsExports on i.ClientID equals s.ClientID into settingGroup
from sg in settingGroup.DefaultIfEmpty()
join sl in settingLots on new {client = sg.ClientID, lot = sg.LotID} equals
new {client = sl.ClientID, lot = sl.ID} into lotsGroup
from lg in lotsGroup.DefaultIfEmpty()
join se in db.Settings_ExportSites on new {client = lg.ClientID, lotId = i.LotID, site = siteId}
equals new {client = se.ClientID, lotId = se.LotID, site = se.Site} into exportGroup
from eg in exportGroup.DefaultIfEmpty()
join f in inventoryFeatures on new {inv = i.ID, cli = i.ClientID} equals
new {inv = f.InventoryID, cli = f.ClientID} into invFeatGroup
from ifg in invFeatGroup.DefaultIfEmpty()
join p in inventoryPhotos on i.ID equals p.InventoryID into photo
from photos in photo.DefaultIfEmpty()
orderby i.ID
select new {i, m, sg, photoo = photo.ToList(), lg, ifg, eg}
into grouped
// group grouped by new {grouped.i.ClientID } into groupedDone
// select groupedDone
select new NewType
{
InventoryVehicles = grouped.i,
InventoryDescriptions = grouped.m,
SettingsExports = grouped.sg,
InventoryPhotos = grouped.photoo,
SettingsLots = grouped.lg,
InventoryFeatures = grouped.ifg,
SettingsExportSites = grouped.eg
}
).AsNoTracking().ToListAsync();
if (longReturnListt != null) returnList.AddRange(longReturnListt);
}
catch (Exception exception)
{
Console.WriteLine(exception);
throw;
}
return returnList;
Doing some stuff linq left join query but facing some problem. Not able to get proper result following sql query need to convert into linq
INSERT INTO tbl_service_order_attributes_versioning(ServiceOrderNo, AttributeId, AttributeValue, parentid, AttributeType, Dt_Stamp, VERSION)
SELECT
T.ServiceOrderNo, T.COIID, T.COI_Identifier,
#pid, 'MBM', getDate(), #ORDERVERSION
FROM
#temp1 T
LEFT JOIN
tbl_service_order_attributes_versioning O WITH(NOLOCK)
ON T.ServiceOrderNo = O.ServiceOrderNo COLLATE database_default
AND T.COIID = O.AttributeID
AND O.PARENTID = #pid
WHERE
O.ServiceOrderNo IS NULL
I have converted this query into a Linq query:
var soiAttr = (from s in ctxParser.TBL_SERVICE_ORDER_ATTRIBUTES_VERSIONING
where s.ParentId == parentId
select s).ToList();
var resultJoinCOI = (from soaI in soiAttr
join iFoi in listFOI on soaI.ServiceOrderNo equals iFoi.fulfilmentOrderItemIdentifier
where iFoi.coiId == soaI.AttributeId &&
iFoi.parentId == parentId &&
soaI.ServiceOrderNo == null
select iFoi).ToList();
if (resultJoinCOI.Count > 0)
{
var listToInsert = (from item in resultJoinCOI
select new TBL_SERVICE_ORDER_ATTRIBUTES_VERSIONING
{
ServiceOrderNo = item.fulfilmentOrderItemIdentifier,
AttributeId = item.coiId,
AttributeValue = item.coiIdentifier,
ParentId = parentId,
AttributeType = "MBM",
DT_Stamp = DateTime.Now,
VERSION = orderVersion
});
ctxParser.TBL_SERVICE_ORDER_ATTRIBUTES_VERSIONING.AddRange(listToInsert);
ctxParser.SaveChanges();
}
The code is executed but result are not correct.
You need to use DefaultIfEmpty (https://msdn.microsoft.com/en-us/library/bb360179.aspx). Here's a reading from MSDN: https://msdn.microsoft.com/en-us/library/bb397895.aspx
In your case it would be something like:
var resultJoinCOI = (
from iFoi in listFOI
join soaI in soiAttr on iFoi.fulfilmentOrderItemIdentifier equals soaI.ServiceOrderNo into res
from subIFoi in res.DefaultIfEmpty()
where iFoi.coiId == soaI.AttributeId && iFoi.parentId == parentId && subIFoi == null
select iFoi).ToList();
Following code that execute successfully. and getting right result.
var soiAttr = (from s in ctxParser.TBL_SERVICE_ORDER_ATTRIBUTES_VERSIONING
where s.ParentId == parentId
select s).ToList();
var resultJoinCOI = (from iFoi in listFOI
join soaI in soiAttr on
new
{
ServiceOrderNo = iFoi.fulfilmentOrderItemIdentifier,
AttributeId = iFoi.coiId
}
equals new
{
ServiceOrderNo = soaI.ServiceOrderNo,
AttributeId = soaI.AttributeId
}
into res
from subFoi in res.DefaultIfEmpty()
select new
{
fulfilmentOrderItemIdentifier = iFoi.fulfilmentOrderItemIdentifier,
coiId = iFoi.coiId,
coiIdentifier = iFoi.coiIdentifier,
AttributeId = subFoi == null ? 0 : subFoi.AttributeId,
ParentId = subFoi == null ? parentId : subFoi.ParentId,
ServiceOrderNo = subFoi == null ? string.Empty: subFoi.ServiceOrderNo
});
if (resultJoinCOI != null)
{
if (resultJoinCOI.Count() > 0)
{
var listToInsert = (from item in resultJoinCOI
select new TBL_SERVICE_ORDER_ATTRIBUTES_VERSIONING
{
ServiceOrderNo = item.fulfilmentOrderItemIdentifier,
AttributeId = item.coiId,
AttributeValue = item.coiIdentifier,
ParentId = parentId,
AttributeType = "MBM",
DT_Stamp = DateTime.Now,
VERSION = orderVersion
});
ctxParser.TBL_SERVICE_ORDER_ATTRIBUTES_VERSIONING.AddRange(listToInsert);
ctxParser.SaveChanges();
}
}
In this way we can implement left join in linq. as per above SQL Query(see above sql statement).
I have the following query in controller and I want to store a column value in a variable but I am not being able to iterate it. Here is my code:
var srmas = (
from SRMAs in db.SRMAs
join SRMAStatus in db.SRMAStatus on SRMAs.Status equals SRMAStatus.Id
join PurchaseOrders in db.PurchaseOrders on SRMAs.PONumber equals PurchaseOrders.PONumber
join Suppliers in db.Suppliers on PurchaseOrders.SupplierID equals Suppliers.SupplierID
join SRMADetails in db.SRMADetails on SRMAs.Id equals SRMADetails.SRMAId
where(SRMAs.Id == srmaid)
group SRMADetails by new
{
SRMADetails.Id,
SRMADetails.SRMAId,
SRMADetails.SupplierPartNum,
SRMAs.PONumber,
SRMAs.ActualAmount,
SRMAs.ApprovedOn,
SRMAs.Status,
SRMAs.TrackingNumber,
SRMAs.SupplierRMANumber,
SRMAs.RequestedFromSupp,
SRMAs.CreatedOn,
Suppliers.SupplierName,
SRMAStatus.StatusName,
PurchaseOrders.PODate,
PurchaseOrders.suppliersOrderNumber
} into grp
select new
{
grp.Key.Status,
grp.Key.SRMAId,
grp.Key.Id,
grp.Key.PONumber,
grp.Key.SupplierRMANumber,
grp.Key.ActualAmount,
grp.Key.SupplierPartNum,
grp.Key.RequestedFromSupp,
grp.Key.TrackingNumber,
grp.Key.ApprovedOn,
grp.Key.SupplierName,
grp.Key.StatusName,
grp.Key.PODate,
grp.Key.suppliersOrderNumber,
grp.Key.CreatedOn,
Sum = grp.Sum(SRMADetails => SRMADetails.Cost * SRMADetails.QtyReturned)
}
).ToList();
System.Collections.IEnumerable et = (System.Collections.IEnumerable)srmas;
IEnumerator it = et.GetEnumerator();
while (it.MoveNext())
{
SRMA current = (SRMA)it.Current;
Response.Write(current.Status);
}
ViewBag.SRMAs = srmas.Select(srma => new IndexViewModel
{
Id = srma.SRMAId,
SupplierRMANum = srma.SupplierRMANumber,
SRMADetailsID = srma.Id,
PONumber = srma.PONumber,
CreatedOn = srma.CreatedOn,
SupplierName = srma.SupplierName,
SRMAStatus = srma.StatusName,
Status = srma.Status,
suppliersOrderNumber = srma.suppliersOrderNumber,
PODate = srma.PODate,
Sum = srma.Sum,
TrackingNumber = srma.TrackingNumber,
ActualAmount = srma.ActualAmount
}).ToList();
I just want to get Status value of first record. How do I do it?
After getting my join to work I seem to have gotten stuck on the count bit.
What I am attempting below is get a count of documents printed based on the join below.
What would the code be to get the count per 'guardiandocsrequired'?
var guardianEntityType = new {EntityTypeFK = "GUARDIAN"};
return (from d in dbContext.GuardianDocsRequireds
join p in dbContext.DocumentPrintingLogs on
new { docTypeFK = d.DocTypeFK, entityFK = d.GuardianFK } equals
new { docTypeFK = p.DocTypeFK, entityFK = p.EntityFK }
where d.GuardianFK == entityPK && p.ItemGroupFK == itemGroupID && p.EntityTypeFK == "GUARDIAN"
group d by new
{
d.GuardianFK,
d.DocTypeFK,
d.DocumentType.DocTypeDescription,
d.RequiredStatus
}
into res
select new DocumentsRequired
{
EntityPK = res.Key.GuardianFK,
EntityType = entityType,
DocTypeFK = res.Key.DocTypeFK,
DocTypeDescription = res.Key.DocTypeDescription,
RequiredStatus = res.Key.RequiredStatus,
PrintCount = ???
}
).ToList();
If it helps, I have written the sql to produce exactly what I require as follows:
SELECT gdr.DocRequiredID,gdr.RequiredDate,gdr.GuardianFK,gdr.DocTypeFK,gdr.RequiredStatus,
COUNT(dpl.DocPrintedID) AS documentsPrinted
FROM dbo.GuardianDocsRequired gdr
LEFT OUTER JOIN dbo.DocumentPrintingLog dpl ON gdr.DocTypeFK = dpl.DocTypeFK
AND gdr.GuardianFK = dpl.EntityFK
AND dpl.EntityTypeFK = 'GUARDIAN'
WHERE gdr.GuardianFK = #entityPK
GROUP BY gdr.DocRequiredID,gdr.RequiredDate,gdr.GuardianFK,gdr.DocTypeFK,gdr.RequiredStatus
Do you mean sth like this?
var guardiandocsrequired = (from d in dbContext.GuardianDocsRequireds
join p in dbContext.DocumentPrintingLogs on
new { docTypeFK = d.DocTypeFK, entityFK = d.GuardianFK } equals
new { docTypeFK = p.DocTypeFK, entityFK = p.EntityFK }
where d.GuardianFK == entityPK && p.ItemGroupFK == itemGroupID && p.EntityTypeFK == "GUARDIAN"
group d by new
{
d.GuardianFK,
d.DocTypeFK,
d.DocumentType.DocTypeDescription,
d.RequiredStatus
}
into res
select new DocumentsRequired
{
EntityPK = res.Key.GuardianFK,
EntityType = entityType,
DocTypeFK = res.Key.DocTypeFK,
DocTypeDescription = res.Key.DocTypeDescription,
RequiredStatus = res.Key.RequiredStatus,
PrintCount = ???
}
).ToList();
int cnt = guardiandocsrequired.Count;
return guardiandocsrequired;