Learning Linq is going to be the death of me, hahahaha.
I have a large query to retrieve data for a report. I need to add a sub query to get related data into the result set. The data in the subquery is a float in the database. My error is "Cannot convert type 'System.Linq.IQueryable' to 'float'"
The query is:
var results = from d in db.Deliveries
join j in db.Jobs on d.Job equals j.Job1
join c in db.Customers on j.Customer equals c.Customer1
join ml in db.Material_Locations on j.Part_Number equals ml.Material into t1
from t2 in t1.DefaultIfEmpty()
join uv in db.User_Values on j.User_Values equals uv.User_Values into t3
from t4 in t3.DefaultIfEmpty()
where d.Promised_Date >= calFrom.SelectedDate && d.Promised_Date <= calTo.SelectedDate
where d.Remaining_Quantity > 0
where (t2.Location_ID ?? "") != "MSSICONSMT"
orderby d.Job, c.Name, d.Promised_Date
select new
{
d.Promised_Date,
d.Job,
LocationID = t2.Location_ID ?? "",
d.Shipped_Quantity,
d.Remaining_Quantity,
d.Promised_Quantity,
j.Unit_Price,
on_Hand_Qty = ((double?)t2.On_Hand_Qty) ?? 0.0,
Part_Number = j.Part_Number ?? "",
c.Name,
c.Ship_Lead_Days,
SafetyStk = t4.Decimal1 ?? 0.0,
ShipDate = d.Promised_Date.AddDays(-1 * (c.Ship_Lead_Days ?? 0)),
RemainValue = d.Remaining_Quantity * j.Unit_Price,
Balance = d.Remaining_Quantity > 0 ? d.Remaining_Quantity - (((double?)t2.On_Hand_Qty) ?? 0.0) : 0,
Consignment = ((float)(from x in db.Material_Locations
join jx in db.Jobs on x.Material equals jx.Part_Number
where jx.Job1 == d.Job
&& x.Location_ID == "MSSICONSMT"
select new {x.On_Hand_Qty}))
};
The problem is the "Consignment" line in the select. How do I deal with the anonymous type and get to converted into a float?
Thanks!
Try following :
Consignment = (from x in db.Material_Locations
join jx in db.Jobs on x.Material equals jx.Part_Number
where jx.Job1 == d.Job && x.Location_ID == "MSSICONSMT"
select new {qty = (float)x.On_Hand_Qty}).ToList();
Consignment = (from x in db.Material_Locations
where x.Material == j.Part_Number
&& x.Location_ID == "MSSICONSMT"
select (float?)x.On_Hand_Qty ?? 0.0).ToList()
and I had to add this;
newRow["Consignment"] = thisRow.Consignment.FirstOrDefault();
to store it in the datatable.
Thanks to all who nudge me in the right direction.
Related
I'm trying to convert this to LINQ C#. I am expecting a single result with the most recent data but the LINQ returns 3 results with the individual data.
SQL:
select * from ticket t
join tollBoothShift tbs on t.fkTollBoothShift = tbs.uniqueId
join classification c on c.uniqueId = t.fkClassification
join classificationPrice cp on cp.fkClassification = c.uniqueId
join person p on p.uniqueId = tbs.fkPerson
WHERE convert(date, t.entryDate) = '6/20/2018'
and (convert(time, t.entryDate) >= convert(time, '12:00')
and convert(time, t.entryDate) <= convert(time, '15:00'))
and cp.entryDate = (SELECT MAX(entryDate)
from classificationPrice
where classificationPrice.fkClassification = c.uniqueId
and entryDate <= t.entryDate)
order by convert(time, t.entryDate)
I have attempted to do so here:
from t in context.Ticket
join c in context.Classification on t.FkClassification equals c.UniqueId
join cp in context.ClassificationPrice on c.UniqueId equals cp.FkClassification into cpc
let price = cpc.Where(f => f.FkClassification == c.UniqueId && f.EntryDate <= t.EntryDate).OrderByDescending(p => p.EntryDate).Take(1).FirstOrDefault().Price
join tbs in context.TollBoothShift on t.FkTollBoothShift equals tbs.UniqueId
join p in context.Person on tbs.FkPerson equals p.UniqueId
where t.EntryDate.Date == date.Date && (t.EntryDate.TimeOfDay >= startTime.TimeOfDay && t.EntryDate.TimeOfDay <= endTime.TimeOfDay) && t.Weight != null
orderby t.EntryDate.TimeOfDay
select
new WeighingLogReportModel
{
ticketNumber = t.UniqueId.ToString(),
entryDate = t.EntryDate,
entryTime = t.EntryDate.ToShortTimeString(),
tollBoothNumber = tbs.UniqueId.ToString(),
supervisor = "",
weight = t.Weight,
cost = price.ToString("N2"),
ownerDriver = string.Empty,
tollBoothShift = tbs.StartTime.ToShortTimeString() + " to " + tbs.EndTime.Value.ToShortTimeString() + "h",
licencePlatePrefix = t.LicencePlatePrefix,
licencePlateSuffix = t.LicencePlateSuffix
}
It seems, you missed the last condition in LINQ query
and cp.entryDate = (SELECT MAX(entryDate)
from classificationPrice
where classificationPrice.fkClassification = c.uniqueId
and entryDate <= t.entryDate)
You can covert this condition to LINQ and add it to existing where clause
cp.EntryDate == ClassificationPrice.Where(x=> x.FkClassification == c.UniqueId).Max(y=> y.EntryDate)
So your final where clause will be
where t.EntryDate.Date == date.Date
&& (t.EntryDate.TimeOfDay >= startTime.TimeOfDay
&& t.EntryDate.TimeOfDay <= endTime.TimeOfDay)
&& t.Weight != null
&& cp.EntryDate == ClassificationPrice.Where(x=> x.FkClassification == c.UniqueId).Max(y=> y.EntryDate)
var Getdetails = (from p in XYZDb.tblPulls
join
ro in XYZDb.tblRentalOrders
on p.AffCode equals ro.AffCode.Value
join
tpsb in XYZDb.tblPullSheetBatchProcessings
on p.PullNo.ToString() equals tpsb.PullSheet
select new
{
PullNos = p.PullNo,
AffCode = p.AffCode,
TotalItems = p.TotalItems,
p.PostedOn,
p.UpdatedOn,
p.IsPrinted,
BatchName = tpsb.BatchName
})
.Where(i => i.PostedOn >= from_date && i.PostedOn <= to && i.IsPrinted != null).Distinct();
In the above code only the pullno having BatchName are coming, i want to retrieve all the pullno within that timezone, and if it is batched, then the BatchName will also appear. I am stuck on that. Any kind of help will be appreciated. Feel free to ask any question.
Use left outer join,
var Getdetails = (from p in XYZDb.tblPulls
join
ro in XYZDb.tblRentalOrders
on p.AffCode equals ro.AffCode.Value
join
tpsb in XYZDb.tblPullSheetBatchProcessings
on p.PullNo.ToString() equals tpsb.PullSheet into pt
from batch in pt.DefaultIfEmpty()
select new
{
PullNos = p.PullNo,
AffCode = p.AffCode,
TotalItems = p.TotalItems,
p.PostedOn,
p.UpdatedOn,
p.IsPrinted,
BatchName = (batch == null ? String.Empty : batch.BatchName )
})
.Where(i => i.PostedOn >= from_date && i.PostedOn <= to && i.IsPrinted != null).Distinct();
I need to convert an SQL query to Linq/Lambda expression, I am trying doing the same but not getting the desired results.
SQL:
SELECT b.*, n.notes
FROM Goal_Allocation_Branch as b
INNER JOIN Goal_Allocation_Product as g
on b.Product = g.ProductID
and b.Year = g.Year
left join Goal_Allocation_Branch_Notes as n
on b.branchnumber = n.branch
and n.year = ddlYear
WHERE b.Year = ddlYear
and g.Show = 1
and branchnumber = ddlBranch
I am new to Linq , I am getting error on Join Clause , and X is not containing any data from first Join
var result = (from br in _DB_Branches.Goal_Allocation_Branches
join pr in _DB_Product.Goal_Allocation_Products on new { br.Product, br.Year } equals new {Product= pr.ProductID, Year= pr.Year }
join n in _DB_Notes.Goal_Allocation_Branch_Notes.Where(n => n.Year == ddlYear) on br.BranchNumber equals n.Branch into Notes
from x in Notes.DefaultIfEmpty()
select new BranchNotesViewModel
{
Year = x.Year,
BranchNumber = x.Branch,
ProductID = x.ProdID
}
).ToList();
Update: My First Join clause initially giving error "The type of one of the expression in Join Clause is incorrect " is resolved, when I Changed On Clause
from
"on new { br.Product, br.Year } equals new {pr.ProductID, pr.Year}"
"on new { br.Product, br.Year } equals new {Product=pr.ProductID,Year= pr.Year}"
still not getting desired results as expected from above SQL query. Please advise..
It should be something like this (see note):
var result =
(from br in _DB_Branches.Goal_Allocation_Branches
join pr in _DB_Product.Goal_Allocation_Products
on br.Product equals pr.ProductID
from n in _DB_Notes.Goal_Allocation_Branch_Notes.Where(x=>
x.branch == br.branchnumber
&& x.year == ddlYear
).DefaultIfEmpty()
where
br.Year == ddlYear
&& and br.Year == pr.Year
&& pr.Show == 1
&& br.branchnumber == ddlBranch
select new BranchNotesViewModel
{
Year = ...,
BranchNumber = ...,
ProductID = ...
}
).ToList();
Note: Change the select, to the properties you want.
Edit: fixed some syntax errors.
I finally figured out the correct answer. Working absolutely fine
var result = (from br in _DB_Branches.Goal_Allocation_Branches
join pr in _DB_Product.Goal_Allocation_Products on new { br.Product, br.Year } equals new { Product = pr.ProductID, Year = pr.Year }
join n in _DB_Notes.Goal_Allocation_Branch_Notes.Where(n=>n.Year==ddlYear) on br.BranchNumber equals n.Branch into Notes
where br.Year==ddlYear
&& pr.Show== true
&& br.BranchNumber==ddlBranch
from x in Notes.DefaultIfEmpty()
select new BranchNotesViewModel
{
Year=x.Year,
BranchNumber=x.Branch,
ProductID=br.Product,
Notes = x.Notes,
//All other fields needed
}
).ToList();
I have this linq query:
var sku = (from a in con.MagentoStockBalances
join b in con.MFGParts on a.SKU equals b.mfgPartKey
join c in con.DCInventory_Currents on b.mfgPartKey equals c.mfgPartKey
where a.SKU != 0 && c.dcKey ==6
select new
{
Part_Number = b.mfgPartNumber,
Stock = a.stockBalance,
Recomended = a.RecomendedStock,
Cato = c.totalOnHandQuantity
}).ToList();
Now i need to remove the c.dcKey ==6 condition and have something like this:
var sku = (from a in con.MagentoStockBalances
join b in con.MFGParts on a.SKU equals b.mfgPartKey
join c in con.DCInventory_Currents on b.mfgPartKey equals c.mfgPartKey
where a.SKU != 0
select new
{
Part_Number = b.mfgPartNumber,
Stock = a.stockBalance,
Recomended = a.RecomendedStock,
Cato = c.totalOnHandQuantity where c.dcKey == 6,
Kerry = c.totalOnHandQuantity where c.dcKey == 7
}).ToList();
Something like this:
Cato = c.dcKey == 6 ? c.totalOnHandQuantity : 0,
Kerry = c.dcKey == 7 ? c.totalOnHandQuantity : 0
The ?: syntax is called a conditional operator.
Instead of adding another join, I would use a separate query in a let:
from a in con.MagentoStockBalances
join b in con.MFGParts on a.SKU equals b.mfgPartKey
where a.SKU != 0
let cs = con.DCInventory_Currents.Where(c => b.mfgPartKey == c.mfgPartKey)
select new
{
Part_Number = b.mfgPartNumber,
Stock = a.stockBalance,
Recomended = a.RecomendedStock,
Cato = cs.Single(c => c.dcKey == 6).totalOnHandQuantity
Kerry = cs.Single(c => c.dcKey == 7).totalOnHandQuantity
}
Though I have no idea how well will LINQ to SQL handle a query like this (if it handles it at all).
var query= from x in context.a
where String.IsNullOrEmpty(param1) || (x.p == param1 && x.i == param2)
select x;
When LINQ translates the below syntax to SQL, the (inner) where clause gets moved to the outer-most query. That's super-unfriendly to the database. I wrote this like Hibernate's HQL (is this appropriate?), and I've written SQL for many moons.
Can anyone help explain what gives, or point me in the way of a resolution?
var rc = (
from dv in (
from dv_j in (
from x in adc.JobManagement
join j in adc.Job on x.JobId equals j.JobId
join js in adc.JobStatus on j.StatusId equals js.JobStatusId
join cm in adc.ClientManagement on j.ClientId equals cm.ClientId
join o in adc.User on cm.UserId equals o.UserId
join jm in adc.JobManagement on j.JobId equals jm.JobId
where
(x.UserId == aid || cm.UserId == aid)
&& (j.StatusDate == null || j.StatusDate >= getFromDate())
&& (jm.ManagementRoleCode == MR_MANAGER)
select new
{
j.JobId,
Job = j.InternalName == null ? j.ExternalName : j.InternalName,
JobStatusDate = j.StatusDate,
JobStatus = js.Code,
Owner = o.Username,
Role = jm.ManagementRoleCode
})
join s in adc.Submission on dv_j.JobId equals s.JobId into dv_s
from s in dv_s.DefaultIfEmpty()
select new
{
dv_j.JobId,
dv_j.Job,
dv_j.JobStatusDate,
dv_j.JobStatus,
dv_j.Owner,
dv_j.Role,
s.SubmissionId,
s.CandidateId,
s.SubmissionDate,
StatusDate = s.StatusDate,
StatusId = s.StatusId
})
join c in adc.Candidate on dv.CandidateId equals c.CandidateId into dv_c
join ss in adc.SubmissionStatus on dv.StatusId equals ss.SubmissionStatusId into dv_ss
from c in dv_c.DefaultIfEmpty()
from ss in dv_ss.DefaultIfEmpty()
orderby
dv.StatusId == null ? dv.StatusDate : dv.JobStatusDate descending,
dv.Job,
c.LastName,
c.NickName,
c.FirstName
select new Projects
{
Id = dv.JobId,
Project = dv.Job,
Submitted = dv.SubmissionDate,
Candidate = FormatIndividual(c.LastName, c.FirstName, c.NickName),
Status = dv.StatusId == null ? ss.Code : dv.JobStatus,
StatusDate = dv.StatusId == null ? dv.StatusDate : dv.JobStatusDate,
Role = dv.Role,
Owner = dv.Owner
});
Try breaking down the one statement into two. This would work as it cannot move the where to a place that doesn't exist yet. This does make multiple round trips to the database, but it is better than having most of several large tables being joined then culled. I would try this:
var inMemoryTable = (
from x in adc.JobManagement
join j in adc.Job on x.JobId equals j.JobId
join js in adc.JobStatus on j.StatusId equals js.JobStatusId
join cm in adc.ClientManagement on j.ClientId equals cm.ClientId
join o in adc.User on cm.UserId equals o.UserId
join jm in adc.JobManagement on j.JobId equals jm.JobId
where
(x.UserId == aid || cm.UserId == aid)
&& (j.StatusDate == null || j.StatusDate >= getFromDate())
&& (jm.ManagementRoleCode == MR_MANAGER)
select new
{
j.JobId,
Job = j.InternalName == null ? j.ExternalName : j.InternalName,
JobStatusDate = j.StatusDate,
JobStatus = js.Code,
Owner = o.Username,
Role = jm.ManagementRoleCode
});
var rc = (
from dv in (
from dv_j in inMemoryTable
join s in adc.Submission on dv_j.JobId equals s.JobId into dv_s
from s in dv_s.DefaultIfEmpty()
select new
{
dv_j.JobId,
dv_j.Job,
dv_j.JobStatusDate,
dv_j.JobStatus,
dv_j.Owner,
dv_j.Role,
s.SubmissionId,
s.CandidateId,
s.SubmissionDate,
StatusDate = s.StatusDate,
StatusId = s.StatusId
})
join c in adc.Candidate on dv.CandidateId equals c.CandidateId into dv_c
join ss in adc.SubmissionStatus on dv.StatusId equals ss.SubmissionStatusId into dv_ss
from c in dv_c.DefaultIfEmpty()
from ss in dv_ss.DefaultIfEmpty()
orderby
dv.StatusId == null ? dv.StatusDate : dv.JobStatusDate descending,
dv.Job,
c.LastName,
c.NickName,
c.FirstName
select new Projects
{
Id = dv.JobId,
Project = dv.Job,
Submitted = dv.SubmissionDate,
Candidate = FormatIndividual(c.LastName, c.FirstName, c.NickName),
Status = dv.StatusId == null ? ss.Code : dv.JobStatus,
StatusDate = dv.StatusId == null ? dv.StatusDate : dv.JobStatusDate,
Role = dv.Role,
Owner = dv.Owner
});