I have some linq which returns a list of properties and the number of bookings for a given year. However if a property has no bookings then it is not included in the resultset.
var bookings = from b in db.Bookings
orderby b.PropertyId
where b.StartDate.Year == Year
group b by b.Property.Title into grp
select new { key = grp.Key, cnt = grp.Count() };
How can this be changed to include properties with no bookings?
I'm assuming there's a Properties table based on your code. You need to select from Properties instead:
var bookings = from p in db. Properties
orderby p.Id
group p by p.Title into grp
select new
{
key = grp.Key,
cnt = grp.Count(p => p.Bookings.Where(b => b.StartDate.Year == Year))
};
I guess you should filter on year in the count, then
var bookings = from b in db.Bookings
orderby b.PropertyId
group b by b.Property.Title into grp
select new {
key = grp.Key,
cnt = grp.Count(x => x.StartDate.Year == Year)
};
Related
I am attempting to write a query that returns a list grouped by OrderID and DateTime value. My first query returns a grouped count which is of type:
IGrouping<'a, Foo> SomeList
Now I am attempting to execute a loop to produce a view model of type List<ViewModel> model based on the above. The problem is an Order may contain more than 1 item OrderLines, I wanted to add a check if the count is > 1 then loop through the sub items and create an object to add to the List object.
var query = (from o in db.Orders
join ol in db.OrderLines on o.OrderID equals ol.OrderID
join u in db.Users on o.UserSalesID equals u.UserID
join r in db.Reports on o.UserSalesID equals r.UserId
where o.Timestamp <= timeNow && o.Timestamp >= timeYesterday && u.UserID == o.UserSalesID
group ol by new { o.Timestamp, o.OrderID } into g
select g).ToList();
// the loop
foreach (var orderLineList in query)
{
foreach (var item in orderLineList) // how to get a count of OrderLineList here
{
// check if count is more than 1 then create an annon object and get total price of order etc
// if not then carry on as normal
model.Add(new ReportViewModel()
{
Gross = orderLineList.Sum(ol => ol.RetailPrice),
Net = orderLineList.Sum(ol => ol.RetailPrice), // minus expense,
PaymentType = orders.Where(o => o.OrderID == item.OrderID).FirstOrDefault().PaymentID,
Quantity = db.OrderLines.Where(ol => ol.OrderID == item.OrderID).Sum(ol => ol.Quantity),
OrderID = item.OrderID
});
}
}
I want to use that query in ef:
select count(number) as CountOfNumber ,number, name from table_1 group by number, name order by CountOfNumber desc
How can I use count on column and add this column new name.
You need to use GroupBy, OrderBy and Count combination:
var results = (from item in db.table_1
group item by new { item.name, item.number } into grouping
orderby grouping.Count() descending
select new
{
name = grouping.Key.name,
number = grouping.Key.number,
CountOfNumber = grouping.Count()
}).ToList();
https://msdn.microsoft.com/en-us/library/bb545971.aspx
You can use the Count method on the group. Where context is your Entity Framework data context or any IEnumerable.
var results = from t in context.table_1
group t by new { t.number, t.name } into g
orderby g.Count() descending
select new { number = g.Key.number, name = g.Key.name, count = g.Count() };
I need extra where clause for my Linq query. For example if customer choose a date filter so i need to date filter to my query etc... When i try to myQuery.Where predicate there is visible just group by's field.
How can i append new where condition to my query.
//for example i need dynamically append o.OrderDate==Datetime.Now or another where clause
var myQuery =(from o in _db.Orders
join l in _db.OrderLines.Where(x => x.ParaBirimi == model.ParaBirimi) on o.orderId equals
l.OrderId
where o.OrderDate.Value.Year == year1
group o by new {o.OrderDate.Value.Month}
into g
select
new
{
Month = g.Key.Month,
Total = g.Select(t => t.OrderLines.Sum(s => s.OrderTotal)).FirstOrDefault()
});
You are too late at the end of the query to add new Where. You have already grouped the data, and projected it, removing nearly all the fields.
Try:
var baseQuery = from o in _db.Orders
join l in _db.OrderLines.Where(x => x.ParaBirimi == model.ParaBirimi) on o.orderId equals l.OrderId
where o.OrderDate.Value.Year == year1
select new { Order = o, OrderLine = l };
if (something)
{
baseQuery = baseQuery.Where(x => x.Order.Foo == "Bar");
}
var myQuery = (from o in baseQuery
group o by new { o.Order.OrderDate.Value.Month }
into g
select
new
{
Month = g.Key.Month,
Total = g.Sum(t => t.OrderLine.OrderTotal)
});
Clearly you can have multiple if. Each .Where() is in && (AND) with the other conditions.
Note how the result of the join is projected in an anonymous class that has two properties: Order and OrderLine
I have this Linq query:
from i in data.Items
join tdi in data.TDItems on i.itemId equals tdi.itemId
group i by i.ItemId
into selection
select new
{
itemId = selection.Key
number = selection.Sum(x => x.quantity) // quantity is a field in TDItems
}
How do I create this sum function? because I'm grouping by an attribute in the Items table, I can't call a Sum on the TDItems table.
group new { i, tdi } by i.ItemId
...
select new
{
selection.Sum(x => x.tdi.quantity)
}
from c in (from i in #as
join tdi in bs on i.itemId equals tdi.itemId
select new
{
itemId = i.itemId,
quantity = tdi.quantity
})
group c by c.itemId
into selection
select new
{
itemId = selection.Key,
number = selection.Sum(x => x.quantity) // quantity is a field in TDItems
};
I have the following LINQ query:
var query =
(from p in obj1
group p by p.objID into g
let totalSum = g.Sum(p => p.ObjPrice)
select new { MyObjectID = g.Key, totalSum })
.Max(g => g.totalSum);
I want to select both the object id and price of the object with the maximum price. How can I do that?
Use an order by descending clause and call FirstOrDefault().
(from p in obj1
group p by p.objID into g
let totalSum = g.Sum(p => p.ObjPrice)
orderby totalSum descending
select new { MyObjectID = g.Key, totalSum }).FirstOrDefault();