linq lambda composite key where and group by - mysql

what's the linq lambda expression for the following mysql query
Select Count(*), Users.BusinessName From Offers
inner join Users on Users.UserId = Offers.UserId
inner join RoleUsers on RoleUsers.User_UserId = Users.UserId
inner join Roles on Roles.RoleId = RoleUsers.Role_RoleId
where Roles.RoleName = 'Seller'
group by Users.BusinessName
Counts the Number of Offers and Groups it by the User's Name ( where the User is a seller).
public static List<CountsByUser> NoOffersByUserType()
{
List<Offer> offers;
using (MainDb ctx = new MainDb())
{
var role = ctx.Roles.FirstOrDefault(r => r.RoleName == "Seller");
List<User> users = role.Users.ToList();
offers= ctx.OfertaPret.Any(u => u.User == users).ToList();
//here is the problem u.User ==users
}
List<CountsByUser> requests = offers.GroupBy(o => o.User.BusinessName)
.Select(nl => new CountsByUser
{
name = nl.Key,
number = nl.Count()
})
.ToList();
return requests;
}

offers= ctx.OfertaPret.Include(u=>u.User)
.Where(u => u.User.Roles.Any(r => r.RoleName == "Seller")).ToList();

Related

LINQ query with left outer join only want most recent record

I have seen several answers to this query, but none have worked for me.
We have multiple mySql tables:
shipments
customers
suppliers
rebillingaudits
in my query I want to pull up the shipments with their customer and supplier and the most recent rebillingaudit record. This is what I have:
var results = context.Shipments.AsNoTracking().Where(x => customerIds.Contains(x.CustomerId.Value) && x.ProcessStageFlag == "REBILL_AUDIT")
.Join(context.Customers.AsNoTracking(),
im => im.CustomerId,
cu => cu.CustomerId,
(im, cu) => new { Shipments = im, Customers = cu }).DefaultIfEmpty()
.Join(context.Suppliers.AsNoTracking(),
im => im.Shipments.SupplierId,
su => su.SupplierId,
(im, su) => new { Shipments = im.Shipments, Customers = im.Customers, Suppliers = su }).DefaultIfEmpty()
.GroupJoin(context.RebillingAudit.AsNoTracking().OrderByDescending(x => x.LastUpdatedOn), //.Take(1),
im => new {im.Shipments.TrackingNumber, im.Shipments.CarrierInvoiceNumber},
rn => new {rn.TrackingNumber, CarrierInvoiceNumber = rn.InvoiceNumber},
(im, rn) => new { MatchingAssignments = im.MatchingAssignments, Shipments = im.Shipments, Suppliers = im.Suppliers, MatchResolutions = im.MatchResolutions, Customers = im.Customers, RebillingAudit = rn })
.SelectMany(
x => x.RebillingAudit.DefaultIfEmpty(),
(x, y) => new { MatchingAssignments = x.MatchingAssignments, Shipments = x.Shipments, Suppliers = x.Suppliers, MatchingResolutions = x.MatchResolutions, Customers = x.Customers, RebillingAudit = y })
.Where(x => x.MatchingAssignments.IsRebill &&
x.MatchingAssignments.IsActive)
.Select(m => new CustomerRebills()
{
TrackingNumber = m.Shipments.TrackingNumber,
Customer = m.Customers.InternalCustomerName,
CarrierInvoice = m.Shipments.CarrierInvoiceNumber,
RebillNotes = m.RebillingAudit == null ? "" : m.RebillingAudit.Notes
}).ToList();
This is the SQL query that I am attempting to replicate:
FROM invoice_master im
JOIN customer c ON im.VPL_customer_ID = c.Customer_ID
JOIN supplier s ON im.Supplier_ID = s.Supplier_ID
LEFT OUTER JOIN rebilling_audit rn ON im.Tracking_Number = rn.tracking_number AND im.Invoice_Number = rn.Invoice_number AND rn.last_updated_on =
(SELECT MAX(last_updated_on) FROM rebilling_audit WHERE tracking_number = im.tracking_number AND Invoice_number = im.invoice_number)
I have tried adding .Take(1) and I do not get what I expect.
I have tried .FirstOrDefault() and I get an error.
Thanks,
Sammer
Using my SQL to LINQ Recipe, translating the SQL more or less directly, I get
var results = (from im in context.InvoiceMaster
join c in context.Customers on im.CustomerId equals c.CustomerId
join s in context.Suppliers on im.Shipments.SupplierId equals s.SupplierId
join rn in context.RebillingAudit on new { im.Shipments.TrackingNumber, im.Shipments.CarrierInvoiceNumber } equals new { rn.TrackingNumber, CarrierInvoiceNumber = rn.InvoiceNumber } into rnj
from rn in rnj.Where(rn => rn.LastUpdatedOn == context.RebillingAudit.Where(ra => ra.TrackingNumber == im.Shipments.TrackingNumber && rn.InvoiceNumber == im.Shipments.CarrierInvoiceNumber).Max(rn => rn.LastUpdatedOn)).DefaultIfEmpty()
select new CustomerRebills() {
TrackingNumber = im.Shipments.TrackingNumber,
Customer = c.InternalCustomerName,
CarrierInvoice = im.Shipments.CarrierInvoiceNumber,
RebillNotes = rn == null ? "" : rn.Notes
}).ToList();
This is what I did to get the latest record:
var results = context.Shipments.AsNoTracking().Where(x => customerIds.Contains(x.CustomerId.Value) && x.ProcessStageFlag == "REBILL_AUDIT")
.Join(context.Customers.AsNoTracking(),
im => im.CustomerId,
cu => cu.CustomerId,
(im, cu) => new { Shipments = im, Customers = cu }).DefaultIfEmpty()
.Join(context.Suppliers.AsNoTracking(),
im => im.Shipments.SupplierId,
su => su.SupplierId,
(im, su) => new { Shipments = im.Shipments, Customers = im.Customers, Suppliers = su }).DefaultIfEmpty()
.GroupJoin(context.RebillingAudit.AsNoTracking().OrderByDescending(x => x.LastUpdatedOn), //.Take(1),
im => new {im.Shipments.TrackingNumber, im.Shipments.CarrierInvoiceNumber},
rn => new {rn.TrackingNumber, CarrierInvoiceNumber = rn.InvoiceNumber},
(im, rn) => new { MatchingAssignments = im.MatchingAssignments, Shipments = im.Shipments, Suppliers = im.Suppliers, MatchResolutions = im.MatchResolutions, Customers = im.Customers, RebillingAudit = rn })
.SelectMany(
x => x.RebillingAudit.DefaultIfEmpty(),
(x, y) => new { MatchingAssignments = x.MatchingAssignments, Shipments = x.Shipments, Suppliers = x.Suppliers, MatchingResolutions = x.MatchResolutions, Customers = x.Customers, RebillingAudit = y })
.Where(x => x.MatchingAssignments.IsRebill &&
x.MatchingAssignments.IsActive)
.Select(m => new CustomerRebills()
{
TrackingNumber = m.Shipments.TrackingNumber,
Customer = m.Customers.InternalCustomerName,
CarrierInvoice = m.Shipments.CarrierInvoiceNumber,
RebillNotes = m.RebillingAudit == null ? "" : m.RebillingAudit.Notes
}).ToList().OrderByDescending(x => x.RebillNotesWhen).GroupBy(y => new {y.TrackingNumber, y.CarrierInvoice, y.BillToAccount, y.CustomerId}).Select(z => z.FirstOrDefault()).ToList();
All my changes are in the last line.
I added an OrderByDescending to get the most recent record to the top, I added a GroupBy to collect each individual role, then I only take the first with the FirstOrDefault.
This resulted in me getting one record per TrackingNumber, CarrierInvoice, BillToAccount, and CustomerId and making sure that the one record was the latest.
I hope this helps someone.
Sammer

LINQ: Count Users in 3 way join

I'm having trouble with LINQ to SQL, which I think should not be too difficult.
In SQL I have a BusinessUnits, that get's divided in OrgUnits, and Users belong to an Org Unit.
I want to print the BusinessUnitID with the number of Users in each.
In SQL, it will probably look like this:
SELECT BusinessUnitID, Count(u.UserID)
FROM BusinessUnitsOrgUnits bu
INNER JOIN OrgUnits org on bu.OrgUnitID= org.OrgUnitID
INNER JOIN Users u on org.OrgUnitID = u.OrgUnitID
GROUP BY BusinessUnitID
But in LINQ I got this, but struggling to get the count correct.
var UsersPerBU = from bu in BusinessUnitsOrgUnits
join org in OrgUnits on bu.OrgUnitID equals org.OrgUnitID
join u in Users on org.OrgUnitID equals u.OrgUnitID
group bu by bu.BusinessUnitID into g
select new
{
BusinessUnitID = g.Key,
UserCount = Users.Count (us => us.OrgUnit.OrgUnitID == bu.OrgUnitID)
//here it complains that bu does not exist.
};
var UsersPerBU = from bu in BusinessUnitsOrgUnits
join org in OrgUnits on bu.OrgUnitID equals org.OrgUnitID
join u in Users on org.OrgUnitID equals u.OrgUnitID
group bu by bu.BusinessUnitID into g
select new
{
BusinessUnitID = g.Key,
UserCount = g.Count()
};
Maybe this
var UsersPerBU = (from bu in BusinessUnitsOrgUnits
join org in OrgUnits on bu.OrgUnitID equals org.OrgUnitID
join u in Users on org.OrgUnitID equals u.OrgUnitID
group bu by bu.BusinessUnitID into g
select new { bu = g})
.Select(x =>
new
{
BusinessUnitID = x,
UserCount = x.bu.Select(y => y.OrgUnitID).Distinct().Count()
//here it complains that bu does not exist
}
);

How to specify multiple condition in Join statement rather than in Where block in NHibernate QueryOver

The following QueryOver generates the Subquery in the Where block but i was rather looking for the way to specify that condition on the join statement
var productsWithLatestComments = _sessionHelper.GetSession().QueryOver(() => p)
.Left.JoinAlias(() => p.Comments, () => cm)
.WithSubquery.Where(() => cm.CommentDate == QueryOver.Of<Comment>()
.Where(c => c.Product.Id == p.Id)
.SelectList(list => list.SelectMax(c => c.CommentDate)).As<DateTime>())
.Where(() => p.Status != "NOT SOLD" )
.SelectList(list => list ....GET THE LIST OF COLS.........
This GENERATES something like
SELECT this_.id as y0_, ......... FROM product this_
left outer join comment cn1_ on this_.id=cn1_.product_id
WHERE cn1_.comment_date = (SELECT max(this_0_.created_date) as y0_ FROM comment this_0_ WHERE this_0_.product_id = this_.id) and (not (this_.status = ?p0);?p0 = 'Sold Out'' [Type: String (18)]
But i was looking for
SELECT this_.id as y0_, ......... FROM product this_
left outer join comment cn1_ on this_.id=cn1_.product_id and cn1_.comment_date = (SELECT max(this_0_.created_date) as y0_ FROM comment this_0_ WHERE this_0_.product_id = this_.id)
WHERE (not (this_.status = ?p0);?p0 = 'Sold Out'' [Type: String (18)]
Ok i got it with some changes in the QueryOver by specifying the subquery inside the join alias rather than inside .WithSubquery
var productsWithLatestComments = _sessionHelper.GetSession().QueryOver(() => p)
.JoinAlias(() => p.Comments, () => cm, JoinType.LeftOuterJoin, Subqueries.Where(() => cm.CommentDate == QueryOver.Of<Comment>()
.Where(c => c.Product.Id == p.Id)
.SelectList(list => list.SelectMax(c => c.CommentDate)).As<DateTime>()))
.Where(() => p.Status != "NOT SOLD" )
.SelectList(list => list ....GET THE LIST OF COLS.........

Doctrine DQL - Expected end of string, got 'inner'

I'm trying to perform kinda simple query, but I always get this exception
[Syntax Error] line 0, col 157: Error: Expected end of string, got
'inner'
Here's my query:
public function hasRecord($user, $event)
{
$q = $this->getEntityManager()->createQuery("
select count(h.id) from Tsk\FEBundle\Entity\History h
inner join h.user u where u.id = :user
inner join h.event v and v.id = :event
");
$q->setParameters([
"user" => $user,
"event" => $event
]);
return $q->getSingleScalarResult();
}
How can I perform two inner joins ? Is there something wrong with my query ?
You should do your joins before where clause:
public function hasRecord($user, $event)
{
$q = $this->getEntityManager()->createQuery("
select count(h.id) from Tsk\FEBundle\Entity\History h
inner join h.user u
inner join h.event v
where u.id = :user
and v.id = :event
");
$q->setParameters([
"user" => $user,
"event" => $event
]);
return $q->getSingleScalarResult();
}

how would i use GroupBy in this linq statement?

Morning i would like to include a group by in this linq statement, Some records i have being brought back have multiple entries so i need to group them by the productAsin. so i dont have duplicates in my table.
var query = from a in dc.aProducts
join t in dc.tProducts on a.sku equals t.sku
join lp in dc.LowestPrices on a.asin equals lp.productAsin
orderby t.title
select new GetLowestPrices
{
productAsin = lp.productAsin,
sku = t.sku,
title = t.title,
tweprice = Convert.ToString(t.twePrice),
lowprice = Convert.ToString(lp.price),
amzprice = Convert.ToString(lp.tweAmzPrice),
lastupdated = Convert.ToDateTime(lp.priceDate)
};
return query.ToList();
many thanks in advance.
Use GroupBy Extension method:
var query = from a in dc.aProducts
join t in dc.tProducts on a.sku equals t.sku
join lp in dc.LowestPrices on a.asin equals lp.productAsin
orderby t.title
select new GetLowestPrices
{
productAsin = lp.productAsin,
sku = t.sku,
title = t.title,
tweprice = Convert.ToString(t.twePrice),
lowprice = Convert.ToString(lp.price),
amzprice = Convert.ToString(lp.tweAmzPrice),
lastupdated = Convert.ToDateTime(lp.priceDate)
};
var groupedData = query.GroupBy(d => d.productAsin);
return groupedData;
After that you can access that group values and put some aggregate function on them as below:
var groupedData = query.GroupBy(d => d.productAsin).Select( data => new {
productAsin = data.Key,
LowPriceSum = data.Sum(s => Convert.ToInt32(s.price))
}).ToList();
Ref:
group clause (C# Reference)
How to Use LINQ GroupBy