Linq Sum for Multiple Joins - linq

Can someone help me out with the following Linq statement? I'm trying to get join 4 tables through Linq, group by the last table and sum a property of the first.
var payments = (
from payment in db.Payments
join payees in db.cmsMembers on payment.PayeeID equals payees.nodeId
join payeeGroups in db.cmsMember2MemberGroups on payees.nodeId equals payeeGroups.Member
join groups in db.umbracoNodes on payeeGroups.MemberGroup equals groups.id
group groups by new {groups.text, payment} into groupedPayments
select new
{
Group = groupedPayments.Key.text,
Count = groupedPayments.Count(),
Amount = groupedPayments.Sum(?)
}
).ToList();
The issue I'm having is that the in the groupedPayments.Sum(..) call I'm only getting access to the "groups" object. This is fine for the Group name and count aspect but the SUM has to be performed on the payment.Amount property.

I've managed to resolve my issue. I hadn't realised that the object in the group declaration would become the actual object witin the resulting group item. By altering the original statement to the following:
group payment by groups into groupedPayments
it seems that each instance of groupedPayments.Key in the select statement now corresponds to the payment row which is what I required.

Related

Trying to update a field in Oracle based on a select statement - getting subquery returns more than one row error

I am trying to update a field on a table the query needs to get the value from a 2nd table and use that to get the data from a 3rd table. I keep getting the "ORA-01427: single-row subquery returns more than one row" Any help is appreciated.
update ord_detail set cuser1 = (select c.email from contact c,ord_detail m join orders o on o.ID = m.orders_ID where c.email is not null)
where EXISTS (select email from contact,orders where orders.contact_id2 = contact.id)
Since you did not provide further information like the results of your sub selects, it's not 100% clear what exactly is your problem. You should check those results and if this does not answer your question, please provide the details.
My guess is that this sub query will give multiple rows because you are missing a join from the table "contact" to one of the other tables:
select c.email from contact c,ord_detail m
join orders o on o.ID = m.orders_ID where c.email is not null
Therefore, this sub query will always lead to many rows as result unless the table "contact" contains one row only whose column email is not null.

How can I get distinct results from this LINQ query?

Below is my ERD and sample data. Note, I'm using Entity Framework and Code first to control my database.
For the project named Vacation, return all the DISTINCT users who have a "true" value in UserBooleanAttributes table for either the Parents or Teens rows defined in the UserAttributes table.
Here is my current attempt:
var myQuery =
from P in context.Projects
join UA in context.UserAttributes on P.ProjectID equals UA.ProjectID
join UBA in context.UserBooleanAttributes on UA.UserAttributeID equals UBA.UserAttributeID
join U in context.Users on UBA.UserID equals U.UserID
where P.ProjectID == 1
where UBA.Value == true
where (UA.UserAttributeID == 1 || UA.UserAttributeID == 2)
select new { uba = U };
This returns 6 users, with e#acme.org being listed twice. Is there a LINQ way of returning distinct values? I suppose I could convert this to a list then filter, but I'd rather have the Database do the work.
I'd rather avoid using lambda expressions if possible. Once again, I want the database to do the work, and not have to write code to union/intersect result groups.

ORACLE Select list inconsistant with group by

I can't create my view and I don't know how to fix it.
when trying to create the view it tries to add all the columns from select to the group by, which isn't what I want. and doesn't work anyways
CREATE OR REPLACE FORCE VIEW CustomerSaleHistoryView AS
Select SALE.SaleID,
SALE.SaleDate,
CUSTOMER.LastName,
CUSTOMER.FirstName,
SALE_ITEM.SaleItemID,
SALE_ITEM.ItemID,
ITEM.ItemPrice,
SUM(SALE_ITEM.ITEMPRICE),
AVG(SALE_ITEM.ITEMPRICE)
from customer
join sale on customer.CUSTOMERID = Sale.CUSTOMERID
join sale_item on sale_item.saleid = sale.saleID
join item on sale_item.itemID = item.itemID
group by CUSTOMER.LastName, CUSTOMER.FirstName, SALE.SaleID;
In order for you query to work you MUST group by any columns that are not being aggregated with a formula like SUM() or AVG(). In your case GROUP BY SALE.SaleID, SALE.SaleDate, CUSTOMER.LastName, CUSTOMER.FirstName, SALE_ITEM.SaleItemID, SALE_ITEM.ItemID, ITEM.ItemPrice
What are you trying to accomplish that you don't believe this GROUP BY is appropriate?
When using group by clause the list of columns that you are selecting should be either part of the group by clause or they should be part of an aggregate function. In your case SALE.SaleDate, SALE_ITEM.SaleItemID, SALE_ITEM.ItemID and ITEM.ItemPrice doesn't satisfy that rule. You need to include these to your group by clause. Once you fix the select statement and when it returns the desired output convert that into a view.

Linq left outer group by, then left outer the group

I've this query that i'm trying to put as linq:
select *
from stuff
inner join stuffowner so on so.stuffID = stuff.stuffID
left outer join (select min(loanId) as loanId, stuffownerId from loan
where userid = 1 and status <> 2 group by stuffownerId) t on t.stuffownerid = so.stuffownerid
left outer join loan on t.LoanId = loan.LoanId
when this is done, I would like to do a linq Group by to have Stuff has key, then stuffowners + Loan as value.
I can't seem to get to a nice query without sub query (hence the double left outer).
So basically what my query does, is for each stuff I've in my database, bring the owners, and then i want to bring the first loan a user has made on that stuff.
I've tried various linq:
from stuff in Stuffs
join so in StuffOwners on stuff.StuffId equals so.StuffId
join tLoan in Loans on so.StuffOwnerId equals tLoan.StuffOwnerId into tmpJoin
from tTmpJoin in tmpJoin.DefaultIfEmpty()
group tTmpJoin by new {stuff} into grouped
select new {grouped, fluk = (int?)grouped.Max(w=> w.Status )}
This is not good because if I don't get stuff owner and on top of that it seems to generate a lot of queries (LinqPad)
from stuff in Stuffs
join so in StuffOwners on stuff.StuffId equals so.StuffId
join tmpLoan in
(from tLoan in Loans group tLoan by tLoan.StuffOwnerId into g
select new {StuffOwnerId = g.Key, loanid = (from t2 in g select t2.LoanId).Max()})
on so.StuffOwnerId equals tmpLoan.StuffOwnerId
into tmptmp from tMaxLoan in tmptmp.DefaultIfEmpty()
select new {stuff, so, tmptmp}
Seems to generate a lot of subqueries as well.
I've tried the let keyworkd with:
from tstuffOwner in StuffOwners
let tloan = Loans.Where(p2 => tstuffOwner.StuffOwnerId == p2.StuffOwnerId).FirstOrDefault()
select new { qsdq = tstuffOwner, qsdsq= (int?) tloan.Status, kwk= (int?) tloan.UserId, kiwk= tloan.ReturnDate }
but the more info i get from tLoan, the longer the query gets with more subqueries
What would be the best way to achieve this?
Thanks

Linq To Entity Framework selecting whole tables

I have the following Linq statement:
(from order in Orders.AsEnumerable()
join component in Components.AsEnumerable()
on order.ORDER_ID equals component.ORDER_ID
join detail in Detailss.AsEnumerable()
on component.RESULT_ID equals detail.RESULT_ID
where orderRestrict.ORDER_MNEMONIC == "MyOrderText"
select new
{
Mnemonic = detail.TEST_MNEMONIC,
OrderID = component.ORDER_ID,
SeqNumber = component.SEQ_NUM
}).ToList()
I expect this to put out the following query:
select *
from Orders ord (NoLock)
join Component comp (NoLock)
on ord .ORDER_ID = comp.ORDER_ID
join Details detail (NoLock)
on comp.RESULT_TEST_NUM = detail .RESULT_TEST_NUM
where res.ORDER_MNEMONIC = 'MyOrderText'
but instead I get 3 seperate queries that select all rows from the tables. I am guessing that Linq is then filtering the values because I do get the correct values in the end.
The problem is that it takes WAY WAY too long because it is pulling down all the rows from all three tables.
Any ideas how I can fix that?
Remove the .AsEnumerable()s from the query as these are preventing the entire query being evaluated on the server.

Resources