LINQ - Where, Group Sum - c#

I have this SQL code:
select A.Recurso_Id, sum(case when B.cita_id is null then 0 else 1 end) as Total_Eventos, a.Recurso_Nombre, a.Recurso_Email,a.Recurso_Activo
from Agenda_Recurso a left join Agenda_Cita B
on A.Recurso_Id=B.Recurso_Id
where B.Cita_Fecha_Final > getdate()
group by A.Recurso_Id, a.Recurso_Nombre, a.Recurso_Email, a.Recurso_Activo
And, I need to traslate to LINQ, actually I have this code:
public List<Recurso> Cantidad_Eventos_Recurso(string pConexion, long pEmpresa, long pSucursal)
{
DateTime dt = DateTime.Now;
List<TRegAgendaCita> _LstCitas = MetodosEnLinea.Catalogo.AgendaEvento_Lista(pConexion, pSucursal);
List<TRegAgendaRecurso> _LstRecursos = MetodosEnLinea.Catalogo.AgendaRecurso_Lista(pConexion, pEmpresa);
if (_LstCitas == null)
return null;
List<Recurso> _ListaSelect = (from Recursos in _LstRecursos
join Citas in _LstCitas on Recursos.Id equals Citas.Recurso_Id
where Citas.Fecha_Final > dt
into cleft
select new Recurso()
{
Cantidad_Eventos = cleft.Where(x => x.Recurso_Id == Recursos.Id).Count(),
Nombre = Recursos.Nombre,
Email = Recursos.Email,
Activo = Recursos.Activo,
Id = Recursos.Id
})
.ToList();
return _ListaSelect;
}
But, in the section that I want to buy the final date with today, he tells me that he is wrong, he says:A query body must end with a select clause or a group clause. Somebody could help me?

The syntax for your query should look like this:
from Recursos in _LstRecursos
join Citas in _LstCitas.Where(c => c.Fecha_Final > dt) // notice the where moved here
on Recursos.Id equals Citas.Recurso_Id
into cleft
select new Recurso()
{
Cantidad_Eventos = cleft.Where(x => x.Recurso_Id == Recursos.Id).Count(),
Nombre = Recursos.Nombre,
Email = Recursos.Email,
Activo = Recursos.Activo,
Id = Recursos.Id
}
You can't put an into clause after where in query syntax. If you want query syntax you can use this, which is a little more verbose:
from Recursos in _LstRecursos
join Citas in
from c in _LstCitas
where c.Fecha_Final > dt
select c
on Recursos.Id equals Citas.Recurso_Id
into cleft
select new Recurso()
{
Cantidad_Eventos = cleft.Where(x => x.Recurso_Id == Recursos.Id).Count(),
Nombre = Recursos.Nombre,
Email = Recursos.Email,
Activo = Recursos.Activo,
Id = Recursos.Id
}

Related

LINQ: join multiple Table Column using Linq and find aggregated sum from child table values

I'm using Linq (code-first approach) query to retrieve the data from DB and couldn't able to get similar result while using below linq query:
from msi in db.MainSaleInvoiceTbls
join dsi in db.DetialSaleInvoiceTbls on msi.Id equals dsi.MainSaleInvoiceId
join ca in db.CustomerAccounts on msi.CustomerId equals ca.Id
join cg in db.MiscLists on ca.CustomerGroupId equals cg.Id
where msi.IsActive == true && msi.CompanyId == UniversalInfo.UserCompany.Id && msi.MainSaleInvoiceDataType == MainSaleInvoiceType.SOInvoice
group msi by new { dsi,msi.Date,msi.FinancialVoucher,msi.SaleOrderPrefix,msi.SaleOrderNumber,msi.SalesId,ca.CustomerName,ca.AccountCode,cg.Name }
into mainSaleInvoice
from dx in mainSaleInvoice.DefaultIfEmpty()
// orderby main.Id
select new
{
Date = mainSaleInvoice.Key.Date,
Voucher = mainSaleInvoice.Key.FinancialVoucher,
InvoiceAccount = mainSaleInvoice.Key.AccountCode,
CustomerName = mainSaleInvoice.Key.CustomerName,
CustomerGroup = mainSaleInvoice.Key.Name,
Invoice = mainSaleInvoice.Key.SaleOrderPrefix + mainSaleInvoice.Key.SaleOrderNumber,
PurchaseOrder = mainSaleInvoice.Key.SalesId,
SalesTax = "",
InvoiceAmount = mainSaleInvoice.Sum(x => (Double)(mainSaleInvoice.Key.Quantity * mainSaleInvoice.Key.UnitPrice))
}).ToList()
In linq, i need to get shortdatetimeString() and sum() of (unitprice* quantity) from child table DetialSaleInvoiceTbls
being new in query writing, I don't know where and what I'm doing wrong. Any suggestions would be much appreciated.
var list=from msi in db.MainSaleInvoiceTbls
join dsi in db.DetialSaleInvoiceTbls on msi.Id equals dsi.MainSaleInvoiceId
join ca in db.CustomerAccounts on msi.CustomerId equals ca.Id
join cg in db.MiscLists on ca.CustomerGroupId equals cg.Id into a
where msi.IsActive == true && msi.CompanyId == UniversalInfo.UserCompany.Id
&& msi.MainSaleInvoiceDataType == MainSaleInvoiceType.SOInvoice
from cg in a.DefaultIfEmpty()
select new
{mainSaleInvoice.Date,
mainSaleInvoice.FinancialVoucher,mainSaleInvoice.AccountCode,
mainSaleInvoice.CustomerName,mainSaleInvoice.Name,
mainSaleInvoice.SaleOrderPrefix, mainSaleInvoice.SaleOrderNumber,
mainSaleInvoice.SalesId, }).sum(x=>x. (mainSaleInvoice.Quantity *
mainSaleInvoice.UnitPrice)).groupby msi new
{msi.Date,msi.FinancialVoucher,msi.SaleOrderPrefix,msi.SaleOrderNumber,
msi.SalesId};
Date = mainSaleInvoice.Date;
Voucher = mainSaleInvoice.FinancialVoucher;
InvoiceAccount = mainSaleInvoice.AccountCode;
CustomerName = mainSaleInvoice.CustomerName;
CustomerGroup = mainSaleInvoice.Name;
Invoice = mainSaleInvoice.SaleOrderPrefix +
mainSaleInvoice.SaleOrderNumber;
PurchaseOrder = mainSaleInvoice.SalesId;
SalesTax = "";
InvoiceAmount =list;

Converted sql query to linq but not getting any result

As I am new to Linq and Entity Framework.
The following is my working stored procedure which includes a value that is a comma separated string (the SUBSTRING clause)
SELECT DISTINCT
SR.StudentRequestId,
SR.RegistrationId,
SR.Location,
SR.PaymentMethod,
SR.CreatedOn,
C.ClassName,
CC.CampusName,
CASE WHEN ISNULL(TSR.StatusId,0)=0 THEN 1 ELSE TSR.StatusId END AS StatusId,
SUBSTRING(
(SELECT', ' + REPLACE(REPLACE(ST1.FromTime,'AM',''),'PM','') + '-'+ ST1.ToTime AS [text()]
FROM dbo.StudentRequestTimings ST1
WHERE ST1.StudentRequestId = SRT.StudentRequestId
ORDER BY ST1.CreatedOn FOR XML PATH ('')
), 2, 1000) [Time] FROM StudentRequest SR
INNER JOIN Registration R ON R.RegistrationId = SR.RegistrationId
INNER JOIN Campus CC ON CC.CampusId = R.CampusId
INNER JOIN Class C ON C.ClassId = SR.ClassId
LEFT JOIN TutorClasses TC ON SR.ClassId = TC.ClassId
LEFT JOIN StudentRequestTimings SRT ON SR.StudentRequestId = SRT.StudentRequestId
LEFT JOIN TutorStudentRequest TSR ON TSR.StudentRequestId = SRT.StudentRequestId AND TutorId = #RegistrationId
WHERE TC.RegistrationId = #RegistrationId
ORDER BY SR.CreatedOn DESC
I have a requirement to use this data in a PagedList method that accepts a IQueryable<T> and I want to convert this SP to a LINQ query that returns a IQueryable (internally the PagedList method uses .Skip() and .Take() to perform server side paging).
The following is my attempt so far, but I do not know why i am not getting to get the expected result as getting from SQL query. I think some thing is wrong in my below code. Can any one identify what is wrong in below code?
var model = (from sr in db.StudentRequests
join r in db.Registrations on sr.RegistrationId equals r.RegistrationId
join cc in db.Campus on r.CampusId equals cc.CampusId
join c in db.Classes on sr.ClassId equals c.ClassId
from tc in db.TutorClasses.Where(t => t.ClassId == sr.ClassId).DefaultIfEmpty()
from srt in db.StudentRequestTimings.Where(s => s.StudentRequestId == sr.StudentRequestId).DefaultIfEmpty()
from tsr in db.TutorStudentRequests.Where(t => t.StudentRequestId == srt.StudentRequestId && t.TutorId == registrationid).DefaultIfEmpty()
where tc.RegistrationId == registrationid
select new TutorDashboard
{
StudentRequestId = sr.StudentRequestId,
RegistrationId = sr.RegistrationId,
Location = sr.Location,
PaymentMethod = sr.PaymentMethod,
CreatedOn = sr.CreatedOn,
ClassName = c.ClassName,
CampusName = cc.CampusName,
Time = string.Join(",", db.StudentRequestTimings.Where(p => p.StudentRequestId == sr.StudentRequestId).Select(p => p.FromTime.ToString().Replace("AM", "").Replace("PM", "") + "-" + p.ToTime.ToString())),
}).Distinct();
Can any one help me out for why I am not getting proper result from above linq query?
Issue is that on adding below code to Linq I am facing issue, How can I resolve this
Time = string.Join(",", db.StudentRequestTimings.Where(p => p.StudentRequestId == sr.StudentRequestId).Select(p => p.FromTime.ToString().Replace("AM", "").Replace("PM", "") + "-" + p.ToTime.ToString())),
I had added this code because I want to get a single string from multiple row
1:00-1:30 PM, 2:00=2:30 PM
5:00-5:30 PM
Like wise
As there was an issue in converting comma seperated code I had implement below code
var query = (from sr in db.StudentRequests
join r in db.Registrations on sr.RegistrationId equals r.RegistrationId
join cc in db.Campus on r.CampusId equals cc.CampusId
join c in db.Classes on sr.ClassId equals c.ClassId
from tc in db.TutorClasses.Where(t => t.ClassId == sr.ClassId).DefaultIfEmpty()
from srt in db.StudentRequestTimings.Where(s => s.StudentRequestId == sr.StudentRequestId).DefaultIfEmpty()
from tsr in db.TutorStudentRequests.Where(t => t.StudentRequestId == srt.StudentRequestId && t.TutorId == registrationid).DefaultIfEmpty()
where tc.RegistrationId == registrationid
select new
{
StudentRequestId = sr.StudentRequestId,
RegistrationId = sr.RegistrationId,
Location = sr.Location,
PaymentMethod = sr.PaymentMethod,
CreatedOn = sr.CreatedOn,
ClassName = c.ClassName,
CampusName = cc.CampusName,
StatusId = tsr.StatusId == null ? 1 : tsr.StatusId,
Time = db.StudentRequestTimings.Where(p => p.StudentRequestId == sr.StudentRequestId).Select(p => p.FromTime.ToString().Replace("AM", "").Replace("PM", "") + "-" + p.ToTime)
}).ToList().GroupBy(p => new { p.StudentRequestId }).Select(g => g.First()).ToList();
var model = query.AsEnumerable().Select(x => new TutorDashboard
{
StudentRequestId = x.StudentRequestId,
RegistrationId = x.RegistrationId,
Location = x.Location,
PaymentMethod = x.PaymentMethod,
CreatedOn = x.CreatedOn,
ClassName = x.ClassName,
CampusName = x.CampusName,
StatusId = x.StatusId == null ? 1 : x.StatusId,
Time = string.Join(",", x.Time),
}).ToList().ToPagedList(page ?? 1, 1);
May this code will be helpful to some who need comma separated value with multiple left join

C# - LINQ - Sum a field from other table

I need to join two tables (Movimientos and Cuentas), group by CuentasId and make a SUM of Movimientos.Monto
Movimientos has a CuentasId to join this, and I can get the data from Cuentas but can not get the Sum.
This is my best approach, any help will be preciated, I'm a little confused with the syntax. Thanks in advance and kind regards,
var cuentas = (from mov in _data.Movimientos
join ct in _data.Cuentas
on mov.CuentasId equals ct.CuentasId
where ct.IsDeleted == 0 && mov.IsDeleted == 0
group ct by new
{
CuentasId = ct.CuentasId,
Alias = ct.Alias,
Moneda = ct.Monedas.Nombre,
Signo = ct.Monedas.Signo,
Banco = ct.Bancos.Nombre
} into ctg
select new
{
Alias = ctg.Key.Alias,
Moneda = ctg.Key.Moneda,
Signo = ctg.Key.Signo,
Banco = ctg.Key.Banco,
Monto = ctg.Sum(mov.Monto)
}
).ToList();
You need to group the value you want to sum like this
group mov.Monto by new { ..... } into ctg
Then ctg will be a collection of mov.Monto values grouped by your list of properties of ct and you'd just call Sum on ctg in your select
Monto = ctg.Sum()
So your new query would be
var cuentas = (from mov in _data.Movimientos
join ct in _data.Cuentas
on mov.CuentasId equals ct.CuentasId
where ct.IsDeleted == 0 && mov.IsDeleted == 0
group mov.Monto by new
{
CuentasId = ct.CuentasId,
Alias = ct.Alias,
Moneda = ct.Monedas.Nombre,
Signo = ct.Monedas.Signo,
Banco = ct.Bancos.Nombre
} into ctg
select new
{
Alias = ctg.Key.Alias,
Moneda = ctg.Key.Moneda,
Signo = ctg.Key.Signo,
Banco = ctg.Key.Banco,
Monto = ctg.Sum()
}).ToList();
You could also try grouping by first and then just summing the items later:
var cuentas = (from mov in _data.Movimientos.Where(w => w.IsDeleted == 0).GroupBy(g => g.CuentasId)
join ct in _data.Cuentas.Where(w => w.IsDeleted == 0).GroupBy(g => new { CuentasId = g.CuentasId, Alias = g.Alias, Monedas = g.Monedas.Nombre, Signo = g.Monedas.Signo, Banco = g.Bancos.Nombre })
on mov.Key.CuentasId equals ct.Key.CuentasId
select new
{
Alias = ct.Key.Alias,
Moneda = ct.Key.Moneda,
Signo = ct.Key.Signo,
Banco = ct.Key.Banco,
Monto = mov.Sum(s => s.Monto)
}
).ToList();

Converting SQL to Linq in c#

I am trying to convert some SQL Code to c# Linq:
SELECT Username, Count(Ticket.TicketId) as 'Tickets Completed'
FROM Ticket
INNER JOIN TicketStatus ON Ticket.TicketStatusID = TicketStatus.TicketStatusID
INNER JOIN Membership ON Ticket.CompletedBy = Membership.UserId
WHERE Ticket.ClosedDate >= #StartDate
and Ticket.ClosedDate <= #EndDate
GROUP BY Username
ORDER BY 'Tickets Completed' DESC
which displays
Paul 6
Mike 4
Donna 3
Elliot 2
I tried to use Linqer which made this more complicated and didnt return any results:
var query = from Ticket in data.Tickets
join Membership in data.Memberships on new { CompletedBy = Guid.Parse(Ticket.CompletedBy.ToString()) } equals new { CompletedBy = Membership.UserId }
where
Ticket.ClosedDate >= StartDate &&
Ticket.ClosedDate <= EndDate
group new { Membership, Ticket } by new
{
Membership.Username
} into g
orderby
"Tickets Completed" descending
select new
{
Username = g.Key.Username,
Completed = g.Count(p => p.Ticket.TicketID > 0)
};
Your help would be appreciated.
Thanks
Assuming CompletedBy and UserId columns are both uniqueidentifier in the database, you shouldn't need to do any type conversion.
var query = from t in db.ticket
join ts in db.ticketStatus
on t.TicketStatus.ID equals ts.TicketStatusID
join m in db.Membership
on t.CompletedBy equals m.UserId
where t.ClosedDate >= startDate
&& t.closedDate <= endDate
group t by m.UserName into tGroup
order by tGroup.Count(t=> t.TicketId) decending
select new {
UserName = tGroup.Key,
TicketCount = tGroup.Count()
};

Linq record not in other table

i want to know how to select those record which is not in another table.
I have a query to show all the stock in a period of time
var query = (from stk in ie.stocks
join s in ie.staffs on stk.stk_createby equals s.stf_id
where stk.stk_createdate >= startDate &&
stk.stk_createdate <= endDate
select new
{
StockID = stk.stk_id,
RefNo = stk.stk_ref_id,
Weight = stk.stk_weight,
Grade = stk.stk_grade,
Remark = stk.stk_remark,
StaffName = s.stf_name
}).ToList();
And also i have another query to show all delivered stock.
var query2 = (from ol in ie.orderLists
join stk in ie.stocks on ol.ol_stockid equals stk.stk_id
join dl in ie.deliveries on ol.ol_dlyid equals dl.dly_id
join s in ie.staffs on stk.stk_createby equals s.stf_id
where dl.dly_delivery_date >= startDate &&
dl.dly_delivery_date <= endDate
select new
{
StockID = stk.stk_id,
RefN = stk.stk_ref_id,
Weight = stk.stk_weight,
Grade = stk.stk_grade,
Remark = stk.stk_remark,
StaffName = s.stf_name
}).ToList();
So what i want is to show the remain stock which is not deliver. How to exclude all stock in query2?
Try Except method.
ex)
var ret = query1.Except(query2);

Categories