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
});
}
}
Related
I need to store multiple values that satisfies specific condition to lstfile.
For that I declare:
List<AlbumPhotos> lstfile = new List<AlbumPhotos>();
And used the below code to get the id of just installed records in T_SelectionListDetails:
idList = (from s in context.T_SelectionListDetails
orderby s.ID descending
select new AlbumPhotos { ID= s.ID }).Take(i).ToList();
where i is the variable that hold how many records saved right now.Then I need to join the T_SelectionListDetails table with T_UserAlbumDetails .Following code is used for that and it will return multiple result but I can't get the entire result but only one.
foreach(var item in idList)
{
lstfile = (from s in context.T_SelectionListDetails
join p in context.T_UserAlbumDetails on s.UserAlbumDetails_ID equals p.ID
where s.ID == item.ID
select new AlbumPhotos
{
virtualPath = p.VirtualPath,
ID = s.ID
}).ToList();
// lstfile.Add(t);
}
how can I get the full result?
You should use AddRange to add the elements of one collection to the end of the other list.
foreach(var item in idList)
{
var lstfile1 = (from s in context.T_SelectionListDetails
join p in context.T_UserAlbumDetails on s.UserAlbumDetails_ID equals p.ID
where s.ID == item.ID
select new AlbumPhotos
{
virtualPath = p.VirtualPath,
ID = s.ID
}).ToList();
lstfile.AddRange(lstfile1);
}
You are assigning the lstfile in foreach loop which will replace old value in each new iteration. And after the loop it would contain the value that is assigned in last iteration of foreach loop.
Better you update your code :
foreach(var item in idList)
{
var lstRows = (from s in context.T_SelectionListDetails
join p in context.T_UserAlbumDetails on s.UserAlbumDetails_ID equals p.ID
where s.ID == item.ID
select new AlbumPhotos
{
virtualPath = p.VirtualPath,
ID = s.ID
}).ToList();
lstfile.AddRange(lstRows);
}
I think what you are looking for is to pass all the ID at once instead looping through it.
lstfile = (from s in context.T_SelectionListDetails
.Where(c => idList.Select(n => n.ID)
.Contains(c.ID))
join p in context.T_UserAlbumDetails on
s.UserAlbumDetails_ID equals p.ID
select new AlbumPhotos
{
virtualPath = p.VirtualPath,
ID = s.ID
}).ToList();
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)
};
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 written a small query and in Linqpad its working well but (see below) Tariffs is not returned as Iqueryable, does anyone know how to fix this ?
Basically see Tariffs = new ....,
from v in House
join gvt in
(from t in MyTariffs where t.Id == 3 select t)
on v.IdTariff equals gvt.Id
select new
{
Id = v.Id,
Tariffs = new
{
Deposit = gvt.CurrentDeposit
}
}
I did try this but its invalid because gvt isn't a table or something?
from v in House
join gvt in
(from t in MyTariffs where t.Id == 3 select t)
on v.IdTariff equals gvt.Id
select new
{
Id = v.Id,
Tariffs = from x in gvt // NOTICE i am doing from x in gvt... But it fails..
select new
{
Deposit = gvt.CurrentDeposit
}
}
Of course gvt contains just the values i want because it has the inner join...
I could do just pull directly from my MyTariffs (which works it returns Iqueryable) but then i have too much info as its not taking into consideration the join which i did in gvt?
from v in House
join gvt in
(from t in MyTariffs where t.Id == 3 select t)
on v.IdTariff equals gvt.Id
select new
{
Id = v.Id,
Tariffs = from x in MyTariffs // THIS has nothing to do with my join
select new
{
Deposit = gvt.CurrentDeposit
}
}
Select the data in a subquery -- are you sure that Id == 3 and Id == v.IdTariff? If that's really the case, then you could add a where clause to the outer query to select only v when v.IdTariff == 3. I'm assuming, though, that you want them all.
var q = from v in House
select new {
Id = v.Id,
Tariffs = (from g in MyTariffs
where g.Id == v.IdTariff
select g.CurrentDeposit)
};
Grouped example (uncompiled/untested), in response to your comments.
var q = from v in House
join g in (from t in MyTariffs where t.Id == 3 select t)
group by v.Id into gvt
select new {
Id = gvt.Key,
Tariffs = gvt.g
};