I have written the following SQL-query that illustrates what I'm trying to achieve:
SELECT
K.id,
SUM(BP.pris)
FROM Kunde K
JOIN Booking BO ON K.id = BO.Kunde_id
JOIN Bane_Booking BB ON BO.id = BB.Booking_id
JOIN Banepris BP ON BO.starttid = BP.time
WHERE BO.gratis = 0
GROUP BY K.id;
Basically it's retrieving the total amount spend by customers. Now I'm trying to convert this query into LINQ, as I'm using LINQ to Entities in my application. This is what I have so far:
from kunde in context.Kunde
join booking in context.Booking on kunde equals booking.Kunde
join banepris in context.Banepris on booking.starttid equals banepris.time
from baneBooking in booking.Bane
select new { Kunde = kunde, Booking = booking, BaneBooking = baneBooking, Banepris = banepris };
I would like however to be able to group these in the same LINQ-query so I dont have to group them manually afterwards. How would i go about achieving this?
I need to get the "kunde"-object and the sum of "banepris.pris".
Without your database, I can't test this, but this should be close:
from K in context.Kunde
join BO in context.Booking on K.id equals BO.Kunde_id
join BP in context.Banepris on BO.starttid equals BP.time
where BO.gratis == 0
group new { Kunde = K, Pris = BP.pris } by K.id into g
select new { ID=g.Key, Kunde = g.First().Kunde, Sum = g.Sum(k=>k.Pris)}
Related
I'm currently having a rough time converting my SQL query to LINQ for a school project I'm using WPF and Entity Framework
here is my SQL query (working exactly as I expect)
select IngrediantName,sum(IngrediantQuantity) as Quantity, IngrediantMeasurementUnit from Users
join Shopping_List
on Users.UserID = Shopping_List.ShoppingListID
join List_Item
on List_Item.ShoppingListID = Shopping_List.ShoppingListID
join Ingrediant
on Ingrediant.IngrediantID = List_Item.IngrediantID
where Users.UserID = 1
group by IngrediantName,IngrediantMeasurementUnit
Here is the query that I have so far
var query = from user in dbContext.Users
join shoppingList in dbContext.ShoppingLists on user.UserId equals shoppingList.UserId
join listItem in dbContext.ListItems on shoppingList.ShoppingListId equals listItem.ShoppingListId
join ingrediant in dbContext.Ingrediants on listItem.IngrediantId equals ingrediant.IngrediantId
where currentUserNumber == user.UserId
select new
{
name = ingrediant.IngrediantName,
quantity = ingrediant.IngrediantQuantity,
unit = ingrediant.IngrediantMeasurementUnit,
};
Here is what i try so far
var query = from user in dbContext.Users
join shoppingList in dbContext.ShoppingLists on user.UserId equals shoppingList.UserId
join listItem in dbContext.ListItems on shoppingList.ShoppingListId equals listItem.ShoppingListId
join ingrediant in dbContext.Ingrediants on listItem.IngrediantId equals ingrediant.IngrediantId
where currentUserNumber == user.UserId
group ingrediant by ingrediant.IngrediantQuantity into x
select new
{
name = x.GroupBy(x => x.IngrediantName),
quantity = x.Sum(x => x.IngrediantQuantity),
unit = x.GroupBy(x => x.IngrediantMeasurementUnit),
};
this one return the following error wiches doesn't tell much
Argument type 'System.Linq.IQueryable1[System.Linq.IGrouping2[System.String,Microsoft.EntityFrameworkCore.Query.TransparentIdentifierFactory+TransparentIdentifier2[Microsoft.EntityFrameworkCore.Query.TransparentIdentifierFactory+TransparentIdentifier2
If someone could point me in the right direction I would appreciate it, if you need more info I will provide it for sure
Thanks
UPDATE
I got this working here the answers to the question for anyone else
var query =
from user in dbContext.Users
join shoppingList in dbContext.ShoppingLists
on user.UserId equals shoppingList.UserId
join listItem in dbContext.ListItems
on shoppingList.ShoppingListId equals listItem.ShoppingListId
join ingrediant in dbContext.Ingrediants
on listItem.IngrediantId equals ingrediant.IngrediantId
where currentUserNumber == user.UserId
group ingrediant by new { name = ingrediant.IngrediantName, unit = ingrediant.IngrediantMeasurementUnit } into x
select new
{
name = x.Key.name,
quantity = x.Sum(x => x.IngrediantQuantity),
unit = x.Key.unit,
};
if you look at the group line
group ingrediant by new { name = ingrediant.IngrediantName, unit = ingrediant.IngrediantMeasurementUnit } into x
from my understanding you use the new to create a new selector then you can use x.key.name and x.key.unit where name and unit are simply some variable
I'm trying to make a query in LINQ translating the following T-SQL query:
select b.crs,
d.epg,
d.m,
Count (a.sq_rea) as qt
from t_aaaa a with (nolock)
join t_bbbb b with (nolock) on a.crs = b.crs
join t_cccc c with (nolock) on a.spr = c.spr and c.rsp = 1
join v_dddd d with (nolock) on c.epg = d.epg
Where a.st = 5
group by b.crs, d.epg, d.m
However, I cannot use the aggregate function like this:
var llstData = (from a in lobjaaaaDao.list()
join b in lobjbbbbDao.list() on a.p equals b.p
join c in lobjcccc.listar() on a.u equals c.u
from d in lobjddddDao.list()
where a.w == d.w &&
a.st.Equals(5) &&
d.Indent == false
group a by new { b.xxxx, c.yyyy, c.zzzz } into grp
select new
{
grp.Key.xxxx,
grp.Key.yyyy,
grp.Key.zzzz,
total = a.kkkk.Count() // ERROR ON THIS LINE
}
).ToList();
I am getting this error:
The name a does not exist in th current context
How can I fix the error?
In the last select statement the only parameter from the query you are accessible to is grp; where each group is IGrouping; each group is represented by a key and an IEnumerable which is in your case : IEnumerable<a>. Having said that; you can replace the line total = a.kkkk.Count() with total = grp.SelectMany(v=> v.kkkk).Count() OR total = grp.Sum(a => a.kkkk.Count()) to resolve the issue.
This way total represents the summation of kkkk counts in each a in the group.
I am not able to work with the below join.
Idea is to find any new (AumProductId and IdClient) combinations from AceBiMonthlyDaos to create entry in Investment table with Unique Id, if those AumProductId and IdClient exist in Reference table of Instrument and Financial Account respectively.
var result = (from AceBi in context.AceBiMonthlyDaos
join Inst in context.Instruments
on AceBi.AumProductId equals Inst.AceId
join FinAcct in context.FinancialAccounts
on AceBi.IdClient equals FinAcct.AceClientId
join Invst in context.Investments
on new { Inst.Id, FinAcct.Id } equals { Invst.InstrumentId, Invst.FinaAcctId} into pair
from InvestmentDao in pair.DefaultIfEmpty()
var query = (from AceBi in context.AceBiMonthlyDaos
join Inst in context.Instruments on AceBi.AumProductId equals Inst.AceId
join FinAcct in context.FinancialAccounts on AceBi.IdClient equals FinAcct.AceClientId
join Invst in context.Investments on new { instrumentId = Inst.Id, finAccountId = FinAcct.Id } equals new { instrumentId = Invst.InstrumentId, finAccountId = Invst.FinAcctId }
into pair
from Invst in pair.DefaultIfEmpty()
select new { Inst, FinAcct, Invst }).Distinct();
So I have a SQL view that I've created that provides me what I need. Essentially it's a job position billeting system that shows how many positions have been authorized vs filled (or assigned).
SELECT Companies.Name AS Company, Grades.Name AS Grade, Series.Name
AS Series, Positions.Authorized, COUNT(People.PersonId) AS Assigned
FROM Companies INNER JOIN
Positions ON Companies.Id = Positions.CompanyId INNER JOIN
Series ON Positions.SeriesId = Series.Id INNER JOIN
Grades ON Positions.GradeId = Grades.Id INNER JOIN
People ON Positions.CompanyId = People.CompanyId AND
Positions.SeriesId = People.SeriesId AND Positions.GradeId = People.GradeId
GROUP BY Companies.Name, Grades.Name, Series.Name, Positions.Authorized
Now what I'd like to be able to do is recreate this in a LINQ query. I've almost got it where I need it; however, I can't figure out how to add the counted column at the end that's based on the People table.
Here's my current LINQ query:
var query = from a in db.Companies
join b in db.Positions on a.Id equals b.CompanyId
join c in db.Series on b.SeriesId equals c.Id
join d in db.Grades on b.GradeId equals d.Id
join e in db.People on new { b.CompanyId, b.SeriesId, b.GradeId } equals new { e.CompanyId, e.SeriesId, e.GradeId }
group a by new { CompanyName = a.Name, GradeName = d.Name, SeriesName = c.Name, b.Authorized, e.PersonId } into f
select new { Company = f.Key.CompanyName, Grade = f.Key.GradeName, Series = f.Key.SeriesName, f.Key.Authorized, Assigned = /* needs to be Count(People.PersonId) based on last join */ )};
Thanks in advance for any help you can provide!
Figured it out. The reason why it was posting multiple rows and not doing a proper count on the same row was because in my "group by" I added in "e.PersonId" when it should have simply been removed. I also had to add a few things to make it work on the front-end razor views since it's an anonymous type (this doesn't have anything to do with the original question, but thought I'd give reason to the changes). So the person who removed their answer, you were partially right, but the reason it wasn't working was because of the additional fieldin the group by:
dynamic query = (from a in db.Companies
join b in db.Positions on a.Id equals b.CompanyId
join c in db.Series on b.SeriesId equals c.Id
join d in db.Grades on b.GradeId equals d.Id
join e in db.People on new { b.CompanyId, b.SeriesId, b.GradeId } equals new { e.CompanyId, e.SeriesId, e.GradeId }
group a by new { CompanyName = a.Name, GradeName = d.Name, SeriesName = c.Name, b.Authorized } into f
select new { Company = f.Key.CompanyName, Grade = f.Key.GradeName, Series = f.Key.SeriesName, Authorized = f.Key.Authorized, Assigned = f.Count()}).AsEnumerable().Select(r => r.ToExpando());
And what it looks like on the page:
I am trying to join 3 tables in a query with Linq to get data from all 3 tables. Below is an image of the table schemes:
The query should select: SewagePlantName, CompanyName and Duty
In addition I need to restricts the SewagePlantId to a list of Ids that are given as:
var sewagePlantIds = UnitOfWork.GetAll<UserGroup>()
.Where(group => group.Id == webAppPrincipal.GroupId)
.SelectMany(group => group.SewagePlantId).Select(sewageplant => sewageplant.Id).ToList();
I have difficulties with the order of joining the 3 tables and where/how to restrict the SewagePlantId to the given list.
Can you try something similar to it please for joining part
from d in Duty
join c in Company on d.CompanyId equals c.id
join s in SewagePlant on c.SewagePlantId equals s.id
select new
{
duty = s.Duty.Duty,
CatId = s.Company.CompanyName,
SewagePlantName=s.SewagePlant.SewagePlantName
// other assignments
};
var obj = from trns in context.tblPartyRegistrations
join st in context.tblSellingTrans
on trns.PartyRegId equals st.Fk_PartyRegId
join pt in context.tblPartyRemainings
on trns.PartyRegId equals pt.fk_PartyId
select new
{
trns.Name,
trns.PhoneNo,
trns.Address,
st.RecivedAmount,
st.Date,
st.CustomerType,
st.MilkRate,
st.Mltr,
st.Mkg,
st.NtAmnt,
st.RemaningAmount,
pt.Remainingammount
};