How can the below be converted to LINQ
SELECT Q.MaterialID AS MaterialID, Q.ProductID AS ProductID, QB.Quantity AS Quantity,
Q.ParameterID AS ParameterID, SUM((Q.ParameterValue * Q.Quantity)/Q.TotalTonnes) AS ParameterValue
FROM #Quality Q
INNER JOIN #QuantityBreakdown QB
ON ((Q.MaterialID = QB.MaterialID) OR (Q.MaterialID IS NULL AND QB.MaterialID IS NULL))
AND ((Q.ProductID = QB.ProductID) OR (Q.ProductID IS NULL AND QB.ProductID IS NULL))
GROUP BY Q.MaterialID, Q.ProductID, ParameterID, QB.Quantity
Am upto:
(from final in (from q in qualities
from qb in quantityBreakDowns
where q.MaterialID == qb.MaterialID && q.ProductID == qb.ProductID
select q)
group final by new {final.MaterialID, final.ProductID, final.ParameterID, final.Quantity}
into FinalResult
select new
{
FinalResult.Key.MaterialID,
FinalResult.Key.ProductID,
FinalResult.Key.ParameterID
//QB.Quantity AS Quantity ??
//SUM((Q.ParameterValue * Q.Quantity)/Q.TotalTonnes) AS ParameterValue ??
}
'??' => how to get these.
Is this right way to do ?
Thanks
I don't think we should be doing your LINQ query for you, but rather pointing you in the right direction to learn LINQ to SQL.
Otherwise the next query you have you will be in the same position.
C# 101 Linq to SQL Examples
VB.NET Linq to SQL 101 Examples
http://www.linqpad.com
http://www.hookedonlinq.com
http://dimecasts.net/Casts/ByTag/Linq2Sql
Something like this should do the trick.
I don't to LinqToSql though so you will need to checkup on how to get the IQuerable object. Otherwise this should point you in the right direction.
var results = from q in myIQuerableObject<Quality>
from qb on qb.MaterialId == q.MaterialId or (qb.MaterialId == null && q.MaterialId == null)
select new {Quality = q, Breakdown = qb}
Ok Sorted out this as :
var result = (from final in
(from q in qualities
from qb in quantityBreakDowns
where q.MaterialID == qb.MaterialID && q.ProductID == qb.ProductID
select q)
group final by
new {final.MaterialID, final.ProductID, final.ParameterID, final.Quantity}
into finalResult
select new
{
finalResult.Key.MaterialID,
finalResult.Key.ProductID,
finalResult.Key.ParameterID,
finalResult.Key.Quantity,
ParameterValue = finalResult.Sum(final => (final.ActualValue*final.Quantity/final.TotalTonnes))}).ToList();
Is this right ?
Related
Work on DF 4 vs 2010.Face problem on join on SalSalesOrderDetail with SalSalesOrderFinancial table.
In SalSalesOrderFinancial one record have SalesOrderDetailID=null. Want to get those records whose SalesOrderDetailID is not present in SalSalesOrderFinancial.
To get desired out put write bellow linq syntax,it’s working .Looking for better join syntax .Is there any way to get desired in one join.
var tempBDwithSODetail = (from p in this.Context.SalSalesOrderFinancials
where p.SalesOrderDetailID != null
select p.SalesOrderDetailID).AsEnumerable();
var tempBDwithOutSODetail = (from p in this.Context.SalSalesOrderFinancials where p.SalesOrderDetailID == null select p).AsEnumerable();
var querySOD = (this.Context.SalSalesOrderDetails.Where(item => !tempBDwithSODetail.Contains(item.SalesOrderDetailID))).AsEnumerable();
var tempBDetail = (from p in querySOD
join q in tempBDwithOutSODetail on p.SalesOrderID equals q.SalesOrderID
where q.SalesOrderDetailID == null
select new
{
q.SalesOrderID,
p.SalesOrderDetailID,
q.CurrencyID,
q.BillingPolicyID,
q.BillTypeID,
q.BillingTypeID
}).AsEnumerable();
If have any query please ask.Thanks in advanced.
if i got you, you just need to simple left join between SalSalesOrderDetail and SalSalesOrderFinancial...
var query = (from u in this.Context.SalSalesOrderDetail
join t in this.Context.SalSalesOrderFinancials
on u.SalesOrderDetailID equals t.SalesOrderDetailID into JoinedList
from t in JoinedList.DefaultIfEmpty()
select new
{
SalSalesOrderDetail = t,
SalSalesOrderFinancials = u
})
.Where(u => u.SalSalesOrderFinancials == null)
.ToList();
I want to do a LINQ NOT EXISTS on query MULTIPLE TABLES.
All examples on Google or SO are handling two tables I'm working with three so I'm struggling as a newbie on LINQ on how to reference them correctly.
First I tried this LINQ query
var nocertificates = (
from x in rmdb.t_certificates
from ce in rmdb.t_user_certificates
from u in rmdb.t_users
where u.id == ce.uid && ce.value != x.id
select x).AsEnumerable().Select(x => new ViewModelCheckBox()
{
Value = x.id.ToString(),
Name = x.name,
Checked = false
});
I used the ugly three times from as I'm not that good with creating types for joining.
But that gave wrong result and I realized I had to go for a NOT EXISTS
So I built a new query in T-SQL
This is the SQL query it works!
select distinct * from t_certificates tc
where NOT EXISTS
(
select distinct * from t_users tu, t_user_certificates tuc
WHERE tu.email = 'user#email.com'
and tu.id = tuc.[uid]
and tuc.value = tc.id
)
How would I do that in LINQ?
This is the question, I will award my answer for that!
BUT!
When we are at it... I'm really curious on the answer.. Is it possible to do one LINQ query that return an Ienumerable with both those that EXISTS and NOT EXISTS resulting in an object which will hold DIFFERENT VALUES on the checked property EXISTS -> CHECKED = true NOT EXISTS -> CHECKED = false
This is how I create my object.
.Select(x => new ViewModelCheckBox()
{
Value = x.id.ToString(),
Name = x.name,
Checked = this should be different based on exists or not
});
The LINQ answer should look something like this (untested):
var nocertificates =
from x in rmdb.t_certificates
join tuc in (
from u in rmdb.t_users
join ce in rmdb.t_user_certificates on u.id == ce.uid
select ce.value
) on tuc.value = tc.id into tuc
from y in tuc.DefaultIfEmpty()
where y == null
select x;
This is what I ended up using!
var query = (from tc in rmdb.t_certificates
where !(
from tu in rmdb.t_users
from tuc in rmdb.t_user_certificates
where tu.email == username
&& tu.id == tuc.uid
&& tuc.value == tc.id select tc).AsEnumerable().Any()
select new ViewModelCheckBox()
{ Checked = false,
intconverter = tc.id,
Name = tc.name
});
I have one LINQ query. In that I need to do some calculations. Everything is fine except when null value found in the either one condition then simply it returns null for the whole condition. Can anyone tell me how can i return the some value even there is a null value found in the condition.
Code
var model =
(from q in db.Porders
select new porders()
{
Id = q.Id,
DetCount = (from amtdet in db.PoDetails
where amtdet.PoId == q.Id
select amtdet.Id).Count(),
Amount = (from amtpord in db.Porders
where amtpord.Id == q.Id
select amtpord.Freight + amtpord.Misc - amtpord.Discount
).FirstOrDefault() +
(from amtdet in db.PoDetails
where amtdet.PoId == q.Id
select amtdet.Copies * amtdet.EstUnitPrice
).Sum()
}).ToList();
I think the DefaultIfEmpty() method will be the solution here
var model =
from q in db.Porders
select new porders()
{
DetCount =
db.PoDetails.Count(amtdet => amtdet.PoId == q.Id),
Amount =
(from amtpord in db.Porders
where amtpord.Id == q.Id
select amtpord.Freight + amtpord.Misc - amtpord.Discount)
.DefaultIfEmpty().First()
+
(from amtdet in db.PoDetails
where amtdet.PoId == q.Id
select amtdet.Copies * amtdet.EstUnitPrice)
.DefaultIfEmpty().Sum()
}
Try applying coalescing column ?? 0 operator on nullable columns or on the result of the FirstOrDefault (for the case that condition is not met). Linq to entities will turn this operator into SQL:
CASE WHEN Column IS NOT NULL THEN Column ELSE 0 END
It will look like:
var model =
(from q in db.Porders
select new porders()
{
Id = q.Id,
Amount = (from amtpord in db.Porders
where amtpord.Id == q.Id
select amtpord.Freight ?? 0 + amtpord.Misc ?? 0 - amtpord.Discount ?? 0
).FirstOrDefault() ?? 0 +
(from amtdet in db.PoDetails
where amtdet.PoId == q.Id
select amtdet.Copies ?? 0 * amtdet.EstUnitPrice ?? 0
).Sum() ?? 0
}).ToList();
Let me first assume that there is a navigation property Porder.Details. Next, why do you select the same Porder in a sub query? It seems to me that your query can be simplified as
from q in db.Porders
select new porders()
{
Id = q.Id,
DetCount = q.Details.Count(),
Amount = q.Freight + q.Misc - q.Discount
+ q.PoDetails.Select( d => d.Copies * d.EstUnitPrice)
.DefaultIfEmpty().Sum()
}
If there isn't such a navigation property it is highly recommended to create one. If you can't or don't want to do that for whatever reason, you should group join the detail records in the main query (db.Porders.GroupJoin(db.PoDetails...)).
If the null values are caused by Freight, Misc or Discount to be nullable, use ?? operator: q.Freight ?? 0.
I'm a LINQ Newb and I've got this query, which returns the pages in a survey. (These values are not materialized into a table, for whatever reason.)
//Group all of this data by page
var pages = from fq in db.FormQuestions
where (fq.FormId == id) && fq.Disabled == false
group fq by fq.PageNumber into p
select new DTOs.PageDTO { PageNumber = p.Key.Value };
And then I have this query, which projects all of the leaf-data into DTOs.
var questions = from fq in db.FormQuestions
join q in db.Questions on fq.QuestionId equals q.QuestionId
where (fq.FormId == id) && fq.Disabled == false
//where (fq.FormId == id) && fq.Disabled == false && fq.PageNumber == page
orderby fq.DisplayOrder
select new DTOs.FormQuestionDTO()
{
DisplayOrder = (fq.DisplayOrder.HasValue ? fq.DisplayOrder.Value : 0),
PageNumber = (fq.PageNumber.HasValue ? fq.PageNumber.Value : 0),
QuestionId = q.QuestionId,
QuestionSelectionMode = q.vts_tbQuestionSelectionMode.Description,
QuestionText = q.QuestionText,
Answers =
from answer in q.Answers
join at in db.AnswerTypes on answer.AnswerTypeId equals at.AnswerTypeID
where answer.Disabled == false
orderby answer.DisplayOrder
select new DTOs.AnswerDTO()
{
AnswerId = answer.AnswerId,
AnswerText = answer.AnswerText,
DisplayOrder = answer.DisplayOrder,
AnswerType = at.Description
}
};
Is there a way to join these two neatly? I.e., under each page DTO I want to see the QUestion DTOs, then inside of that Answer DTOs, and onward...
Also, even if I could do this all in one LINQ statement, is it preferable to build the LINQ statements separately and then merge them? This feels a bit like building temp variables in SQL in that it may be possible to build one giant query but it's a pain to maintain.
So why wouldn't something like this work?
//Group all of this data by page
var pages = from fq in db.FormQuestions
where (fq.FormId == id) && fq.Disabled == false
group fq by fq.PageNumber into p
select new DTOs.PageDTO {
PageNumber = p.Key.Value
questions = from fq in db.FormQuestions
join q in db.Questions on fq.QuestionId equals q.QuestionId
where (fq.FormId == id) && fq.Disabled == false
orderby fq.DisplayOrder
select new DTOs.FormQuestionDTO()
{
DisplayOrder = (fq.DisplayOrder.HasValue ? fq.DisplayOrder.Value : 0),
// etc as you 2nd code sample
So I wanted to make a linq query out of my left join sql (refer to it below). I just don't know how to properly position the ".TournamentId = 1" condition on the joins. Currently when running this on my database I get the results that I want. which is a couple of rows from the Type table with null fields.
select typ.Id, stat.PromoterId, temp.PromoterId
from ReportTypes type
left join ReportTemplateStatus status on status.PromoterId = type.TypeId and status.TournamentId = 1
left join ReportTemplates temp on temp.ClientId = status.PromoterId and temp.TournamentId = 1
Promoter
- promoterId
- promoterName
Tournament
- tournamentId
- tournamentName
ReportType
- TypeId
ReportTemplateStatus
- promoterId (this is the key)
- tournamentId
- typeId
ReportTemplates
- promoterId
- tournamentId
This is currently what I have:
var report = from type in context.ReportTypes
join status in context.ReportTemplateStatus on type.TypeId equals status.TypeId
join temp in context.ReportTemplates on status.promoterId equals temp.promoterId into iReports
from reports in iReports.Where (rep => rep.promoterId == _promoterId && rep.tournamentId == _tournamentId).DefaultIfEmpty()
select new { my fields});
but it's giving me a null.
any ideas on how the linq should work? maybe separate into "itables" (iReports) or something?
This should give you what you are looking for
var report = from type in context.ReportTypes
from status in context.ReportTemplateStatus.Where(x => type.TypeId == x.TypeId)
.Where(x => x.TournamentId == 1)
.DefaultIfEmpty()
from reports in context.ReportTemplates.Where(x => status.promoterId == x.promoterId)
.Where(x => x.TournamentId == 1)
.DefaultIfEmpty()
select new { my fields};
You can use like this
var query = from person in people
join pet in pets on person equals pet.Owner into gj
from subpet in gj.DefaultIfEmpty()
select new { person.FirstName, PetName = (subpet == null ? String.Empty : subpet.Name) };
Thanks