LINQ Subquery issue - linq

Following is my linq query:
var varResourceStatusReportDataBase =
(
from content in listContent
join workflowInstance in listWorkflkowInstance
on content.Field<string>("ows_ID").Trim()
equals workflowInstance.Field<string>("ows_Content ID").Split(';')[0].Trim()
join WorkflowInstanceStep in listWorkflowInstanceStep
on workflowInstance.Field<string>("ows_ID")
equals WorkflowInstanceStep.Field<string>("ows_Workflow Instance ID").Split(';')[0]
select new
{
ContentName = content.Field<string>("ows_Name"),
WorkflowInstanceId = workflowInstance.Field<string>("ows_ID"),
WIName = workflowInstance.Field<string>("ows_Title"),
WIPlannedStartDate = workflowInstance.Field<string>("ows_Planned Start Date") ?? "",
WIPlannedEndDate = workflowInstance.Field<string>("ows_Planned End Date") ?? "",
WIActualStartDate = workflowInstance.Field<string>("ows_Actual Start Date") ?? "",
WIActualEndDate = workflowInstance.Field<string>("ows_Actual End Date") ?? "",
WIApprovalDate = workflowInstance.Field<string>("ows_Approval Date") ?? "",
WITaskStatus = workflowInstance.Field<string>("ows_Status").ToUpper() ?? "",
WIMetadataStatus = workflowInstance.Field<string>("ows_Metadata Status") ?? "",
WIApprover = workflowInstance.Field<string>("ows_Approver").Replace("#", "").Split(';')[1].ToUpper() ?? "",
WISResponsible = WorkflowInstanceStep.Field<string>("ows_Responsible").Replace("#", "").Split(';')[1].ToUpper() ?? "",
WISDesiredEndDate=
(
from WorkflowInstanceStep1 in listWorkflowInstanceStep
where (WorkflowInstanceStep1.Field<string>("ows_Status") =="IN PROGRESS" ||
WorkflowInstanceStep1.Field<string>("ows_Status") =="ASSIGNED") &&
workflowInstance.Field<string>("ows_ID") == WorkflowInstanceStep1.Field<string>("ows_Workflow Instance ID").Split(';')[0]
select new {abc = WorkflowInstanceStep1.Field<string>("ows_Desired End Date")}).Take(1)
}).Distinct();
I have sub-query in above query to calculate WISDesiredEndDate, but when I execute this query, I get System.Linq.Enumerable+TakeIterator>d__3a'1[<>f__AnonymousType1'1[System.String]] value for WISDesiredEndDate column not actual value which I want.
Please give suggestion on the same.
Thanks.

You want FirstOrDefault() rather than Take(1)
As from comments, you don't want a anonymous object so change the select to be
select WorkflowInstanceStep1.Field<string>("ows_Desired End Date")}).FirstOrDefault()

You can us let clause more readable code. Nevertheless you have to force linq expression execution by calling FirstOrDefault method
let desiredEndDate = (from WorkflowInstanceStep1 in listWorkflowInstanceStep .... Take(1))
select new
{
...
WISDesiredEndDate= desiredEndDate.FirstOrDefault()
}

Related

LINQ query slow - nested Group By and ToList()

I have the following linq query that takes 10 seconds or more to run - is there a better way of writing it? It works, but is just very slow:
var searchQuery = (from p in db.Property
where p.PropertyVendorId == loggedInUserId
from aues in db.ApplicationUserEvents
where aues.ApplicationUserEventsPropertyId == p.PropertyId
&& aues.ApplicationUserEventsFeedbackDate != null
group p by new { p.PropertyId, p.PropertyAddress1, p.PropertyAddress2, p.PropertyAddress3, p.PropertyZipOrPostcode } into pg
select new DashboardFeedback
{
PropertyNumber = pg.FirstOrDefault().PropertyNumber,
PropertyId = pg.FirstOrDefault().PropertyId,
PropertyReference = pg.FirstOrDefault().PropertyId,
PropertyAddress1 = pg.FirstOrDefault().PropertyAddress1,
PropertyAddress2 = pg.FirstOrDefault().PropertyAddress2,
PropertyZipOrPostcode = pg.FirstOrDefault().PropertyZipOrPostcode,
DashboardFeedbackChart = (
from aues2 in db.ApplicationUserEvents
where aues2.ApplicationUserEventsPropertyId == pg.FirstOrDefault().PropertyId
&& aues2.ApplicationUserEventsFeedbackDate != null
from fos in db.FeedbackOptions
where fos.FeedbackOptionsApplicationUserEventsId == aues2.ApplicationUserEventsId
from fo in db.FeedbackOption
where fos.FeedbackOptionsFeedbackOptionId == fo.FeedbackOptionId
group fo by new { fo.FeedbackOptionName, aues2.ApplicationUserEventsPropertyId } into g
select new DashboardFeedbackChart
{
FeedbackOptionName = g.FirstOrDefault().FeedbackOptionName,
FeedbackOptionNameCount = g.Count()
}).ToList<DashboardFeedbackChart>()
}).ToList();
One Property has many ApplicationUserEvents
One ApplicationUserEvents has many FeedbackOptions
One FeedbackOptions has one FeedbackOption
Thanks for any advice!

Crystal Report - Linq select statement finds nulls in fields

I'm trying to use a Linq query to a custom crystal report in MyReports folder. However, crystal reports engine is complaining of nulls.
I have managed to make a blank for the Serial Number where it might be null, but DateTime is more of an issue for me.
I have tried:
InspectionDate = subpat.InspectionDate == null ? "" : subpat.InspectionDate,
But the error is:
Type of conditional expression cannot be determined because there is no implicit conversion between 'string' and 'System.DateTime?'
I would just want a blank result if null.
My Query:
var today = DateTime.Now.Date;
var tomorrow = today.AddDays(30);
var dateresult = db.ClinicalINSs.GroupBy(d => d.ClinicalAssetID)
.SelectMany(g => g.OrderByDescending(d => d.NextInspectionDate)
.Take(1));
var ClinicalIDVM = (from s in dateresult.Where(q => q.NextInspectionDate <= tomorrow)
join co in db.ClinicalAssets on s.ClinicalAssetID equals co.ClinicalAssetID into AR
let subred = AR.OrderByDescending(subredASS => subredASS.ClinicalAssetID).FirstOrDefault()
join cp in db.ClinicalPATs on s.ClinicalAssetID equals cp.ClinicalAssetID into AP
let subpat = AP.OrderByDescending(SubPATASS => SubPATASS.ClinicalAssetID).FirstOrDefault()
orderby s.NextInspectionDate descending
select new ClinicalIDVM
{
ClinicalAssetID = s.ClinicalAssetID,
ProductName = subred.ProductName,
SerialNo = subred.SerialNo == null ? "" : subred.SerialNo,
InspectionDate = subpat.InspectionDate,
NextInspectionDate = s.NextInspectionDate
}).ToList();
You can try this way
InspectionDate = subpat.InspectionDate == null ? (DateTime?)null : subpat.InspectionDate
or change type of InspectionDate to string, then you will do
InspectionDate = subpat.InspectionDate.HasValue
? subpat.InspectionDate.Value.ToString("yyyy-MM-dd") : "";
Updated
InspectionDate = subpat.InspectionDate == null ? (object) "" : subpat.InspectionDate

How to get the fields from a WorkItem using a WIQL in one call to speed up?

I've have the following code to get some specific WorkItems:
string workItemQueryString = "Select Id, State, Type From WorkItems Where [Work Item Type] = 'Code Review Request' And [Area Path] = 'abc' Order By [Changed Date] Desc";
var workItemQuery = new Query(workItemStore, workItemQueryString);
WorkItemCollection queryResults = workItemQuery.RunQuery();
This code runs fast (< 1 sec). However I also want to get some extra fields like "Associated Context Type" and "Associated Context".
So I use this code get get those fields:
var workItemDetails = queryResults.Cast<WorkItem>().Select(workItem => new WorkItemDetail
{
WorkItem = workItem,
AssociatedContextType = workItem.Fields.Contains("Associated Context Type") ? workItem.Fields["Associated Context Type"].Value : null,
AssociatedContext = workItem.Fields.Contains("Associated Context") ? workItem.Fields["Associated Context"].Value : null
}).ToList();
But this code runs very slow (13 to 20 seconds) which looks to me that separate queries (for each workitem?) are fired to the TFS server to get all data.
Note that when I use a Parallel.ForEach statement, the code breaks with an exception.
The total number of WorkItems in the WorkItemCollection is about 2800.
Try to change:
AssociatedContextType = workItem.Fields.Contains("AssociatedContextType") ? workItem.Fields["AssociatedContextType"].Value : null,
AssociatedContext = workItem.Fields.Contains("AssociatedContext") ? workItem.Fields["AssociatedContext"].Value : null
to:
AssociatedContextType = workItem.Fields.Contains("Associated Context Type") ? workItem.Fields["Associated Context Type"].Value : null,
AssociatedContext = workItem.Fields.Contains("Associated Context") ? workItem.Fields["Associated Context"].Value : null

How do I optimize this LINQ query? It runs localhost but it doesn't run on Azure

I have this LINQ query and am getting results I need. However it takes 5-6 seconds to show results on localhost, and I can't even run this on Azure.
I'm new to LINQ, and I'm sure that I'm doing something inefficient.
Could someone direct me to optimize?
var joblist = (from t in db.Tracking
group t by t.JobNumber into j
let id = j.Max(x => x.ScanDate)
select new
{
jn = j.Key,
ti = j.FirstOrDefault(y => y.ScanDate == id).TrackingId,
sd = j.FirstOrDefault(y => y.ScanDate == id).ScanDate,
lc = j.FirstOrDefault(y => y.ScanDate == id).LocationId
}).Where(z => z.lc == lid).Where(z => z.jn != null);
jfilter = (from tr in joblist
join lc in db.Location on tr.lc equals lc.LocationId
join lt in db.LocType on lc.LocationType equals lt.LocationType
select new ScanMod
{
TrackingId = tr.ti,
LocationName = lc.LocationName,
JobNumber = tr.jn,
LocationTypeName = lt.LocationTypeName,
ScanDate = tr.sd,
StoneId = ""
}).OrderByDescending(z => z.ScanDate);
UPDATE:
This query runs on Azure(s1) but it takes 30 seconds. This table has 500,000 rows and I assume that OrderByDescending or FirstOrDefault is killing it...
var joblist = db.Tracking
.GroupBy(j => j.JobNumber)
.Select(g => g.OrderByDescending(j => j.ScanDate).FirstOrDefault());
jfilter = (from tr in joblist
join lc in db.Location on tr.LocationId equals lc.LocationId
join lt in db.LocType on lc.LocationType equals lt.LocationType
where tr.LocationId == lid
select new ScanMod
{
TrackingId = tr.TrackingId,
LocationName = lc.LocationName,
JobNumber = tr.JobNumber,
LocationTypeName = lt.LocationTypeName,
ScanDate = tr.ScanDate,
StoneId = ""
}).OrderByDescending(z => z.ScanDate);

ajax and ruby script only returning 1 record instead of many

I am doing an Ajax call, using Ruby and Sinatra. The query should return multiple rows, it only returns one though.
The ajax script is:
$(document).ready(function() {
$(".showmembers").click(function(e) {
e.preventDefault();
alert('script');
var short_id = $('#shortmembers').val();
console.log(short_id);
$.getJSON(
"/show",
{ 'id' : short_id },
function(res, status) {
console.log(res);
$('#result').html('');
$('#result').append('<input type=checkbox value=' + res["email"] + '>');
$('#result').append( res["first"] );
$('#result').append( res["last"] );
$('#result').append( res["email"] );
});
});
});
and the Ruby script is:
get '/show' do
id = params['id']
DB["select shortname, first, last, email from shortlists sh JOIN shortmembers sm ON sm.short_id = sh.list_id JOIN candidates ca ON ca.id = sm.candidate_id where sh.list_id = ?", id].each do |row|
#shortname = row[:shortname]
#first = row[:first]
#last = row[:last]
#email = row[:email]
puts #shortname
puts #first
puts #last
puts #email
halt 200, { shortname: #shortname, first: #first, last: #last, email: #email }.to_json
end
end
If I run the query directly in the terminal on postgres I get 9 rows returned but, as above on my website, it just returns the first row only.
What's the problem? No error in the console, just one record.
You have halt 200 inside your loop. This will cause Sinatra to terminate the request processing and return the result back up the stack.
To return a full set of results, you will need to do something like the following:
get '/show' do
id = params['id']
results = DB["select shortname, first, last, email from shortlists sh
JOIN shortmembers sm ON sm.short_id = sh.list_id
JOIN candidates ca ON ca.id = sm.candidate_id
where sh.list_id = ?", id].map do |row|
{
:short_name => row[:shortname],
:first=>row[:first],
:last=>row[:last],
:email=>row[:email]
}
end
halt 200, results.to_json
end
This will return the selected fields from each row as an array of hashes.
In fact, as I look at the above, the solution might even be as simple as:
get '/show' do
id = params['id']
results = DB["select shortname, first, last, email from shortlists sh
JOIN shortmembers sm ON sm.short_id = sh.list_id
JOIN candidates ca ON ca.id = sm.candidate_id
where sh.list_id = ?", id]
halt 200, results.to_json
end
since you don't seem to be selecting anything but the columns you desire in the first place.

Resources