join with multiple group by element and select extra columns - c#

Can you please help to convert this from sql to linq, i am new to linq and been trying this and couldn't succeed. Let me know if this is even possible or not?
SELECT max(Products.ProductID) as ProductID, Products.SKU, Products.Name, Products.RRP, Products.Price,
max(Products.FrontTall) as FrontTall,
ProductsCategory.SortOrder,
Products.ColorValue,
max(Products.ColorImg) as ColorImg,
Products.IsPrimary,
Products.Visible
FROM Products INNER JOIN ProductsCategory ON Products.ProductID = ProductsCategory.ProductID
WHERE (ProductsCategory.CategoryID = 5 ) AND (Products.Visible = 1) AND (Products.Inactive = 0) AND (Products.Deleted = 0 or Products.Deleted is null)
GROUP BY SKU, Products.Name, RRP, Price, ColorValue, ProductsCategory.SortOrder, IsPrimary, Visible
AND this is what i am trying
var products = (from p in db.Products
join cp in db.ProductsCategories on p.ProductID equals cp.ProductID
where cp.CategoryID == catId && p.Visible == true && p.Inactive == false && (p.Deleted == null || p.Deleted == false)
group p by new {
p.SKU,
p.Name,
p.RRP,
p.Price,
p.ColorValue,
p.IsPrimary,
p.Visible,
cp.SortOrder
} into grouped
select new {
ProductID,
FrontTall,
ColorImg,
SKU = grouped.Key.SKU,
Name = grouped.Key.Name,
RRP = grouped.Key.RRP,
Price = grouped.Key.Price,
ColorValue = grouped.Key.ColorValue,
IsPrimary = grouped.Key.IsPrimary,
Visible = grouped.Key.Visible,
SortOrder = grouped.Key.SortOrder
})
.OrderBy(x => x.SortOrder);
I need to get the ProductID, FrontTall and ColorImg field value without including in group by
Thanks in advance.
Kish

select new {ProductID = grouped.Max(x => x.ProductID)}

Related

LINQ GroupBy a name, but how to get Id of users?

I want to display how many transfers did every customer.
I want to display CustomerId, Name and Totaly amount of transfers.
I mean I want to display CustomerId too, not only Name and Amount transfers.
Everything works fine except CustomerId: it is empty in my DataGridview.
I don't know how to do and I would really appreciate any kind of help.
Here is my code:
using (Db db = new Db())
{
var statistic = (from u in db.Transfers
join c in db.Customers on u.CustomerId equals c.CustomerId
where u.IsActive == true && u.Paid == true
group u by c.FirstName into g
select new
{
// here I get Headertext but not Id's value
Id = g.Select(x =>x.CustomerId),
Name = g.Key,
Totaly = g.Sum(x => x.Amount)
}).OrderByDescending(x => x.Totaly).ToList();
if (statistic != null)
{
dgvCustomerList.DataSource = statistic;
}
}
The correct way is to group it by CustomerId (because CustomerId is unique, you will get distinct customers inside select and then you can use FirstOrDefault() for getting FirstName property):
using (Db db = new Db())
{
var statistic = (from u in db.Transfers
join c in db.Customers on u.CustomerId equals c.CustomerId
where u.IsActive == true && u.Paid == true
group u by c.CustomerId into g
select new
{
Id = g.Key, // here I get Headertext but not Id's value
Name = g.FirstOrDefault().FirstName,
Totaly = g.Sum(x => x.Amount)
}).OrderByDescending(x => x.Totaly).ToList();
if (statistic != null)
{
dgvCustomerList.DataSource = statistic;
}
}
You can group by both customerId and FirstName
using (Db db = new Db())
{
var statistic = (from u in db.Transfers
join c in db.Customers on u.CustomerId equals c.CustomerId
where u.IsActive == true && u.Paid == true
group u by new {key c.FirstName,key c.CustumerId} into g
select new
{
Id = g.Key.CustumerId,//g.Select(x =>x.CustomerId), // here I get Headertext but not Id's value
Name = g.Key.FirstName,
Totaly = g.Sum(x => x.Amount)
}).OrderByDescending(x => x.Totaly).ToList();
if (statistic != null)
{
dgvCustomerList.DataSource = statistic;
}
}

LINQ: Multiple Join With Max Revision Filter

So I have this line:
var transrevmax = db.TRANSACTs
.Where(x => x.SITE == "1" &&
x.DATE_IN >= dateinchoice &&
x.DATE_OUT <= dateoutchoice)
.GroupBy(x => x.TICKET_NO)
.Select(x => x.OrderByDescending(y => y.REV_NO).FirstOrDefault())
.ToList();
and it returns the exact list of transactions I want the join below to go through to obtain values from...
var exportrecovery = (from trans in transrevmax
join detail in db.DETAILs on new { TICKET_NO = trans.TICKET_NO, REV_NO = trans.REV_NO } equals new { TICKET_NO = detail.TICKET_NO, REV_NO = detail.REV_NO }
join job in db.JOBs on new { JOB_CODE = trans.JOB_CODE, CUST_CODE = trans.CUST_CODE } equals new { JOB_CODE = job.CODE, CUST_CODE = job.CUST_CODE }
join customer in db.CUSTOMERs on trans.CUST_CODE equals customer.CODE
join invoiced in db.INVOICEDs on trans.TICKET_NO equals invoiced.TICKET_NO
where trans.DATE_IN >= dateinchoice && trans.DATE_OUT <= dateoutchoice && trans.STATUS.ToString().Trim() != "V" && trans.STATUS.ToString().Trim() != "E"
select new { ADDRESS = customer.ADDRESS, CITY = customer.CITY, STATE = customer.STATE, ZIP = customer.ZIP, FREIGHT = detail.HAUL_CHGE + detail.FUEL_CHGE, JOB_NAME = job.NAME, HAUL_TAX = detail.HAUL_TAX, INVOICE_NO = invoiced.INVOICE_NO, CUST_NAME = customer.NAME, TAX_CODE = customer.TAX_CODE, MAT_CHGE = detail.MAT_CHGE, MAT_TAX = detail.MAT_TAX, MAT_CODE = detail.MAT_CODE, QTY = detail.QTY, PRICE = detail.PRICE, DATE_MOD = trans.DATE_OUT, REV_NO = trans.REV_NO, SITE = trans.SITE, TICKET_NO = trans.TICKET_NO, CUST_CODE = trans.CUST_CODE, JOB_CODE = trans.JOB_CODE }
).ToList();
... if I run the first line I get the transactions limited to only those with the max revision (what I want), and if I run the join (replacing the "transrevmax" with the table "db.TRANSACTs") I get the right range of ticket numbers, but it includes all revisions. I am stumped as to how I can use the joined tables and get only unique rows according to their (maximum) revision number. When these two are used in conjunction I receive zero rows. Please advise.
Remove the ToList on the transrevmax creation.

How to get the group sum in my complex linq query

below I have listed a linq query that works properly in my asp.net.mvc web app.
In addition I would like to group over 'allowance.ParameterId' in order to get the group sum for 'allowance.Freight (instead of multiple records for the given key).
var query = from ara in aras
join company in companies on ara.Id equals company.ARAId
join wasteWater in wasteWaters on company.Id equals wasteWater.CompanyId
join allowance in allowances on wasteWater.Id equals allowance.WasteWaterID
join parameter in parameters on allowance.ParameterId equals parameter.Id into JoinedParameterAllowance
from parameter in JoinedParameterAllowance.DefaultIfEmpty()
where company.Activ == true && company.End == null && company.Template == false
&& wasteWater.End == null
select new FreightSummaryViewModel
{
AraName = ara.Name,
AraId = ara.Id,
AllowedParameter = parameter.Name,
AllowedFreight = allowance.Freight
};
I have tried to insert 'group ...' but failed to get it right.
Could someone help me please to set up the proper syntax?
Thank you in advance, Manu
I have little idea about relations in your database, so I improvised...
// Some dummy data to play with
var aras = Enumerable.Range(0, 5).Select(i => new { Id = i, Name = "Ara" + i });
var companies = Enumerable.Range(0, 15).Select(i => new { Id = i, ARAId = i % 5, Activ = true, End = (DateTime?)null, Template = false });
var wasteWaters = Enumerable.Range(0, 35).Select(i => new { Id = i, CompanyId = i / 15, End = (DateTime?)null });
var allowances = Enumerable.Range(0, 70).Select(i => new { Id = i, WasteWaterID = i, ParameterId = i % 4, Freight = i * 1000 });
var parameters = Enumerable.Range(0, 4).Select(i => new { Id = i, Name = "Parameter" + i });
And this is what I believe you looked for:
var query =
from ara in aras
join company in companies on ara.Id equals company.ARAId
join wasteWater in wasteWaters on company.Id equals wasteWater.CompanyId
join allowance in allowances on wasteWater.Id equals allowance.WasteWaterID
join parameter in parameters on allowance.ParameterId equals parameter.Id
into JoinedParameterAllowance
// from parameter in JoinedParameterAllowance.DefaultIfEmpty()
where true
&& company.Activ == true
&& company.End == null
&& company.Template == false
&& wasteWater.End == null
group allowance by new
{
AraName = ara.Name,
AraId = ara.Id,
ParameterId = allowance.ParameterId
} into myGroup
select new //FreightSummaryViewModel
{
AraName = myGroup.Key.AraName,
AraId = myGroup.Key.AraId,
AllowedParameter = myGroup.Key.ParameterId,
AllowedFreight = myGroup.Sum(g => g.Freight)
};

Not counting null values from a linq LEFT OUTER JOIN query

I have this sql query that does exactly what i want but i need it in linq. It returns a few AVC rows and counts how many PersonAVCPermission that has status 1 linked to it
SELECT a.Id, a.Name, a.Address, COUNT(p.AVCID) AS Count
FROM AVC AS a
LEFT OUTER JOIN
(
SELECT PersonAVCPermission.AVCId
FROM PersonAVCPermission
WHERE PersonAVCPermission.Status = 1
) AS p
ON a.Id = p.AVCId
GROUP BY a.Id, a.Name, a.Address
I have this query in linq and it does the same thing except when there are no PersonAVCPermission it still counts 1
var yellows = odc.PersonAVCPermissions.Where(o => o.Status == (int)AVCStatus.Yellow);
var q = from a in odc.AVCs
from p in yellows.Where(o => o.AVCId == a.Id).DefaultIfEmpty()
group a by new { a.Id, a.Name, a.Address } into agroup
select new AVCListItem
{
Id = agroup.Key.Id,
Name = agroup.Key.Name,
Address = agroup.Key.Address,
Count = agroup.Count(o => o.Id != null)
};
Im guessing that with DefaultIfEmpty() it places null rows in the list that then gets counted so i try to exclude them with (o => o.Id != null) but it still counts everything as at least one
If i dont use DefaultIfEmpty() it skips the rows with count 0 completely
How can i exclude them or am i doing it completely wrong?
How about using .Any() and a Let?
var yellows = odc.PersonAVCPermissions.Where(o => o.Status == (int)AVCStatus.Yellow);
var q = from a in odc.AVCs
let Y = (from p in yellows.Where(o => o.AVCId == a.Id) select p).Any()
where Y == true
group a by new { a.Id, a.Name, a.Address } into agroup
select new AVCListItem
{
Id = agroup.Key.Id,
Name = agroup.Key.Name,
Address = agroup.Key.Address,
Count = agroup.Count(o => o.Id != null)
};
You don't need the join, nor the grouping:
var q = from a in odc.AVCs
select new AVCListItem
{
Id = a.Id,
Name = a.Name,
Address = a.Address,
Count = yellows.Where(o => o.AVCId == a.Id).Count()
};

How do I compare a nullable guid to a guid in a linq query?

I'm getting a error when this attempts to run:
Nullable<Guid> ng = corpid;
var qry1 = from c in entities.Transactions
join p in entities.Products on c.CorporationId equals (Nullable<Guid>) p.CorporationId
where c.Branch == br &&
c.AccountNumber == accountnumber &&
c.CorporationId == ng
orderby c.TransactionDate descending
select new
{
Date = c.TransactionDate,
RefNo = c.ReferenceNumber,
DlvryAcct = c.DeliveryAccount,
Desc = p.Description,
GasQty = c.GasQuantity,
Total = c.Amount,
Balance = c.Balance
};
This is the message:
LINQ to Entities does not recognize the method
'System.Linq.IQueryable`1[f__AnonymousType1`7[System.Nullable`1[System.DateTime],
System.String,System.String,System.String,System.Nullable`1[System.Decimal],
System.Nullable`1[System.Decimal],System.Nullable`1[System.Decimal]]]
Reverse[f__AnonymousType1`7](System.Linq.IQueryable`1[f__AnonymousType1`7[System.Nullable`1[System.DateTime],
System.String,System.String,System.String,System.Nullable`1[System.Decimal],
System.Nullable`1[System.Decimal],System.Nullable`1[System.Decimal]]])'
method, and this method cannot be translated into a store expression.
I don't think the cast to nullable guid is working here. The c.CorporationId is a nullable guid but the p.corporationid is just a guid.
Any suggestions?
Have you tried foregoing the casting and equating c.CorporationId to ng.Value instead?:
Nullable<Guid> ng = corpid;
var qry1 = from c in entities.Transactions
join p in entities.Products on c.CorporationId equals p.CorporationId
where c.Branch == br &&
c.AccountNumber == accountnumber &&
c.CorporationId == ng.Value
orderby c.TransactionDate descending
select new
{
Date = c.TransactionDate,
RefNo = c.ReferenceNumber,
DlvryAcct = c.DeliveryAccount,
Desc = p.Description,
GasQty = c.GasQuantity,
Total = c.Amount,
Balance = c.Balance
};
It seems to be complaining about the anonymous constructor in the select clause. c.TransactioDate, c.GasQuantity, c.Amount and c.Balance all appear to be Nullable. Try something like this just to see if those fields are the problem.
Nullable<Guid> ng = corpid;
var qry1 = from c in entities.Transactions
join p in entities.Products on c.CorporationId equals (Nullable<Guid>) p.CorporationId
where c.Branch == br &&
c.AccountNumber == accountnumber &&
c.CorporationId == ng.Value
orderby c.TransactionDate descending
select new
{
Date = c.TransactionDate.Value,
RefNo = c.ReferenceNumber,
DlvryAcct = c.DeliveryAccount,
Desc = p.Description,
GasQty = c.GasQuantity.Value,
Total = c.Amount.Value,
Balance = c.Balance.Value
};
This is an old question, but since there's no answer, here's the skinny. In C# Guid is a non-nullable object, so you can't ever map null to Guid, but you can map Null to Guid?, so here's the solution:
var qry1 = from c in entities.Transactions
join p in entities.Products on c.CorporationId equals p.CorporationId
where c.Branch == branch
&& c.AccountNumber == accountNumber
&& ((Guid?)c.CorporationId).Value == null // This is the secret sauce
orderby c.TransactionDate descending
select new
{
Date = c.TransactionDate,
RefNo = c.ReferenceNumber,
DlvryAcct = c.DeliveryAccount,
Desc = p.Description,
GasQty = c.GasQuantity,
Total = c.Amount,
Balance = c.Balance
};
But, I would probably do this:
var qry1 = from c in entities.Transactions.Where(t => ((Guid?)t.CorporationId).Value == null)
join p in entities.Products on c.CorporationId equals p.CorporationId
where c.Branch == branch
&& c.AccountNumber == accountNumber
orderby c.TransactionDate descending
select new
{
Date = c.TransactionDate,
RefNo = c.ReferenceNumber,
DlvryAcct = c.DeliveryAccount,
Desc = p.Description,
GasQty = c.GasQuantity,
Total = c.Amount,
Balance = c.Balance
};
But you have to ask the question if you are having to cast this why the model has this column identified as not being nullable (if it was set right, you probably wouldn't be faced with having to cast at this point).

Categories

Resources