I don't know how to work with nested selects in LINQ.
How could I convert this SQl expression to LINQ?
Select i.ID, i.Impression,
(Select COUNT(ImpressionsId)
from DiaryImpressions
where DiaryPostsId = '2' AND ImpressionsId = i.ID) as Num from Impressions i
Seriously? DiaryPostsId is a string? Oh well...
from i in context.Impressions
select new {
i.ID,
i.Impressions,
Num = (from d in context.DiaryImpressions
where d.DiaryPostsId == "2"
&& d.ImpressionsId == i.ID
select d).Count()
}
from ...
select new {
i.Id,
i.Impression,
Count = context.DiaryImpressions.Count(d => d.DiaryPostsId == 2 && d.ImpressionsId == i.Id)
}
If you map your objects properly, you can use child relations directly:
Count = i.DiaryImpressions.Count(d => d.DiaryPostsId == 2)
Related
I need to convert my SQL statement to LINQ.
SELECT
dbo.Transactions.TypeRefID,
dbo.TransactionItems.ItemRefID,
SUM(dbo.TransactionItems.Quantity) AS Qty
FROM
dbo.TransactionItems
LEFT OUTER JOIN
dbo.Transactions ON dbo.TransactionItems.TransactionRefID = dbo.Transactions.TransactionID
GROUP BY
dbo.Transactions.TypeRefID, dbo.TransactionItems.ItemRefID
HAVING
(dbo.Transactions.TypeRefID = 1)
AND (dbo.TransactionItems.ItemRefID = 5)
I tried converting the above statement into LINQ and this is what I've done.
var query = from t in db.Transaction
join i in db.TransactionItem on t.TransactionID equals i.TransactionRefID
where t.TypeRefID == 1 && i.ItemRefID == 5
group i by new
{
t.TypeRefID,
i.ItemRefID
} into g
select new
{
TypeRefID = g.Key.TypeRefID,
ItemRefID = g.Key.ItemRefID,
Quantity = g.Sum(q => q.Quantity)
};
When I run my code I get error "System.Linq.Queryable.FirstOrDefault(...) returned null"
I'm using it like this
if (query != null)
string qty = query.FirstOrDefault().Quantity.ToString();
The error is called on "query.FirstOrDefault().Quantity.ToString()"
How to avoid this error?
I am a newbie intern way over my head, I promise I have researched this thoroughly and tried many different things. The following linq query works, but I want to group rows by last and first name and then only show the rows that appear more than once. When I un-comment out the group by statement, all my aliases below become unrecognized and changing them to the actual db.table names doesn't help.
var query = from emps in db.Employees
join c in db.Cards on emps.SbiID equals c.SbiID
where c.StateID == 0 && c.CardNumberNumeric > 100000
//group emps by new {emps.Surname, emps.Name};
//orderby grp.Count() // something like 'where grp.Count > 1
select new
{
Surname = emps.Surname,
Name = emps.Name,
CorpID = emps.Identifier,
CardNum = c.CardNumber,
CostCenter = emps.EmployeeUserField.UF13,
Supervisor = (from e in db.Employees
where
e.Identifier.Equals(emps.EmployeeUserField.UF5)
select e.Surname).FirstOrDefault()
+ ", "
+ (from e in db.Employees
where e.Identifier.Equals(emps.EmployeeUserField.UF5)
select e.Name).FirstOrDefault(),
SupervisorID = emps.EmployeeUserField.UF5,
EmpCommence = emps.CommencementDateTime,
CardCommence = c.CommencementDateTime,
WorkPhone = emps.Telephone,
State = (from cf in db.ComboFields
from sp in db.StringProperties
where cf.ComboIndex.Equals(c.StateID)
&& cf.StringID.Equals(sp.StringID)
&& cf.TableName.Equals("Card")
&& cf.FieldName.Equals("StateID")
select sp.DefaultValue).FirstOrDefault()
};
this.tagsGridView.DataSource = query;
this.tagsGridView.DataBind();
I think the problem you're running into is that you're not flattening out your groups appropriately. For example:
var duplicateEmployees = db.Employees
.GroupBy(emp => emp, new EmployeeComparer())
.Where(grp => grp.Count() > 1)
.SelectMany(grp => grp.AsEnumerable());
var duplicateEmployeeInfo =
from emps in duplicateEmployees
join c in db.Cards on emps.SbiID equals c.SbiID
where c.StateID == 0 && c.CardNumberNumeric > 100000
select new
{
... what to select
};
With:
public class EmployeeComparer : IEqualityComparer<Employee>
{
public bool Equals(Employee x, Employee y)
{
return x.Surname == y.Surname && x.Name == y.Name;
}
public int GetHashCode(Employee obj)
{
unchecked { return (17 * obj.Surname.GetHashCode()) ^ (23 * obj.Name.GetHashCode()); }
}
}
This groups the employees by name, finds the groups that have a count > 1, then returns the elements of those groups. No guarantees on performance, but this should solve your issue.
here's my sql query below:
Can you guys help me to convert this to a much cleaner one??
SELECT [PurchaseRequestID], [ProjectID],[FullName]
FROM PurchaseRequest
WHERE [PurchaseRequestID] IN
(SELECT [PurchaseRequestID] FROM PurchaseRequestDetail )
AND [PurchaseRequestID] NOT IN
(SELECT [PurchaseRequestID] FROM [PurchaseOrder] )
Though i have already converted this successfuly, i think this is not readable and needs to be rewritten:
var query = from a in db.PurchaseRequests
where
(from b in db.PurchaseRequestDetails
select new
{
b.PurchaseRequestID
}).Contains(new { a.PurchaseRequestID }) &&
!(from c in db.PurchaseOrders
select new
{
c.PurchaseRequestID
}).Contains(new { a.PurchaseRequestID })
select a;
thanks
you really don't need all those anonymous objects. Use the let keyword to introduce temporary variables instead of doing operations on the subqueries directly.
from a in db.PurchaseRequests
let b = from b in db.PurchaseRequestDetails select b.PurchaseRequestID
let c = from c in db.PurchaseOrders select c.PurchaseRequestID
where b.Contains(a.PurchaseRequestID) && !c.contains(a.PurchaseRequestID)
select a;
var query = from a in db.PurchaseRequests
where
db.PurchaseRequestDetails.Any(x => x.PurchaseRequestID == a.PurchaseRequestID) &&
!db.PurchaseOrders.Any(x => x.PurchaseRequestID == a.PurchaseRequestID)
select a;
If you have navigation properties set up, you can write the query like this:
IQueryable<PurchaseRequest> query =
from purchaseRequest in myDataContext.PurchaseRequests
where purchaseRequest.PurchaseRequestDetail.Any()
where !purchaseRequest.PurchaseOrder.Any()
select purchaseRequest;
Or this lambda/method style if you prefer...
IQueryable<PurchaseRequest> query2 = myDataContext.PurchaseRequests
.Where(purchaseRequest => purchaseRequest.PurchaseRequestDetail.Any())
.Where(purchaseRequest => !purchaseRequest.PurchaseOrder.Any());
Need help with converting next statement to LINQ:
SELECT * FROM comments
WHERE good_id = '19' AND allow = '1'
ORDER BY IF(parent_id = 0, id, parent_id) DESC, id ASC
It's statement show the comment in next order list:
--Comment
--Subcomment (if parent_id != 0)
--Subcomment (if parent_id != 0)
--Comment
--Subcomment (if parent_id != 0)
etc.
But I don't know how to implement it on LINQ. Any ideas?
have not compiled this but I think I am on the right path.
var comments = from c in db.Comments
where c.good_id == 19 && c.allow = "1"
orderby myFunction(c.parent_id, c.id) descending, id ascending
select comments;
public int myFunction(int parentID, in ID)
{
return parent_id == 0 ? id : parent_id;
}
If models have relationships set up correctly then you don't need to do anything fancy
var comments = dataCoontext.Comments
.Where(c => c.GoodId = 19 &&
c.Allow = 1 &&
c.ParentId = 0) //Get top level comments
.OrderBy(c => c.Id);
foreach(var comment in comments){
Console.WriteLine("Comment:" + comment.Text);
GetSubComments(comment);
}
Then use the following
public void GetSubComments(Comment comment){
foreach(var subComment in comment.Children){ //You can apply any sub ordering to Children
Console.WriteLine("Sub comment:" + subComment.Text);
GetSubComments(subComment);
}
}
select colId,
colTaskType,
MaxID
from tblTaskType
join (
select tblCheckList.colTaskTypeID,
max(colItemNumber) MaxID
from tblCheckList
group by colTaskTypeID
) x on coltaskTypeID = tblTaskType.colID
Assuming you are using linq-to-sql and have the two tables in a datacontext.
The more or less exact translation would be:
var maxChecks = from checks in DataContext.tblChecklist
group checks by checks.colTaskTypeID into g
select new { colTaskTypeID, max = g.Group.Max(x => x.colItemNumber) };
var result = from t in DataContext.tblTaskType
join c in maxChecks on t.colTaskTypeID equals c.colTaskTypeID
select new { t.colId, t.colTaskTypeID, c.max };
But you could try:
var result = from t in DataContext.tblTaskType
select new {
t.colId,
t.colTaskTypeID,
Max = (from c in DataContext.tblChecklist
where c.colTaskTypeID == t.colTaskTypeID
select c.colItemNumber).Max() };