Select Distinct from multiple tables linq to sql - c#

I have tow tables, tblItem and tblInsertLines, in tblInsertLines I have the same ItemId but with differnt ProdDate and ExpireDate, I want to get a distinct list of all items but select the first row from tblInsertLines as the first row contains the oldest ProdDate.
Any help will be appreciated. I use this code.
public static List<Item> getItemList()
{
using (var db = new AWarehouseDataClassesDataContext())
{
var list = (from i in db.tblItems
join e in db.tblInsertLines on i.ItemId equals e.ItemId
orderby i.NameE
select new Item
{
code = i.Code,
itemId = i.ItemId,
lastUpdate = i.LastUpdate,
nameA = i.NameA,
nameE = i.NameE,
qty = i.Qty,
prodDate = e.ProdDate,
expireDate = e.ExpireDate,
updatedBy = i.UpdatedBy
}).Distinct();
return list.ToList();
}
}

You can try
var list= (from i in db.tblItems
join e in db.tblInsertLines on i.ItemId equals e.ItemId
where e.counter > 0
orderby i.NameE
group new { i, e } by e.ItemId into g
select new Item
{
code = g.First().i.Code,
itemId = g.Key,
lastUpdate = g.First().i.LastUpdate,
nameA = g.First().i.NameA,
nameE = g.First().i.NameE,
qty = g.First().i.Qty,
prodDate = g.Min(x=>x.e.ProdDate),
expireDate = g.First().e.ExpireDate,
updatedBy = g.First().i.UpdatedBy
}).ToList();

Related

How to convert to Linq

How to convert the following query into linq
SELECT
a.ProductId,
a.Name,
a.Description,
b.Quoteid,
b.Productid,
b.Quantity,
b.OriginalPrice
FROM
Products AS a
LEFT JOIN
QuoteDtails AS b
ON a.ProductId = b.ProductId
AND b.QuoteId = 200;
Don't know where to add the AND condition.
Thanks and regards
You can try this linq if you want to write LEFT JOIN of linq, you need to add
into [temp collection] from [Left join talbe collection] in [temp collection].DefaultIfEmpty()
after Linq join
look like this.
from ss in Products
join aa in QuoteDtails
on ss.ProductId equals aa.ProductId into temp
from ds in temp.DefaultIfEmpty()
where ds.QuoteId = 200
select new
{
ProductId_P = ss.ProductId,
Name = ss.Name,
Description = ss.Description,
Quoteid = ds.Quoteid,
Productid_Q = ds.Productid,
Quantity = ds.Quantity,
OriginalPrice = ds.OriginalPrice
}
You can add AND condition in your LINQ query like this :
var res = from p in products
join q in quoteDtails on new { Criteria1 = p.ProductID, Criteria2 = 200 } equals new { Criteria1 = q.Productid, Criteria2 = q.Quoteid }
select new
{
ProductId_P = p.ProductID,
Name = p.Name,
Description = p.Description,
Quoteid = q.Quoteid,
Productid_Q = q.Productid,
Quantity = q.Quantity,
OriginalPrice = q.OriginalPrice
};

Getting a field value from a LINQ query without Iteration

I have the following query in controller and I want to store a column value in a variable but I am not being able to iterate it. Here is my code:
var srmas = (
from SRMAs in db.SRMAs
join SRMAStatus in db.SRMAStatus on SRMAs.Status equals SRMAStatus.Id
join PurchaseOrders in db.PurchaseOrders on SRMAs.PONumber equals PurchaseOrders.PONumber
join Suppliers in db.Suppliers on PurchaseOrders.SupplierID equals Suppliers.SupplierID
join SRMADetails in db.SRMADetails on SRMAs.Id equals SRMADetails.SRMAId
where(SRMAs.Id == srmaid)
group SRMADetails by new
{
SRMADetails.Id,
SRMADetails.SRMAId,
SRMADetails.SupplierPartNum,
SRMAs.PONumber,
SRMAs.ActualAmount,
SRMAs.ApprovedOn,
SRMAs.Status,
SRMAs.TrackingNumber,
SRMAs.SupplierRMANumber,
SRMAs.RequestedFromSupp,
SRMAs.CreatedOn,
Suppliers.SupplierName,
SRMAStatus.StatusName,
PurchaseOrders.PODate,
PurchaseOrders.suppliersOrderNumber
} into grp
select new
{
grp.Key.Status,
grp.Key.SRMAId,
grp.Key.Id,
grp.Key.PONumber,
grp.Key.SupplierRMANumber,
grp.Key.ActualAmount,
grp.Key.SupplierPartNum,
grp.Key.RequestedFromSupp,
grp.Key.TrackingNumber,
grp.Key.ApprovedOn,
grp.Key.SupplierName,
grp.Key.StatusName,
grp.Key.PODate,
grp.Key.suppliersOrderNumber,
grp.Key.CreatedOn,
Sum = grp.Sum(SRMADetails => SRMADetails.Cost * SRMADetails.QtyReturned)
}
).ToList();
System.Collections.IEnumerable et = (System.Collections.IEnumerable)srmas;
IEnumerator it = et.GetEnumerator();
while (it.MoveNext())
{
SRMA current = (SRMA)it.Current;
Response.Write(current.Status);
}
ViewBag.SRMAs = srmas.Select(srma => new IndexViewModel
{
Id = srma.SRMAId,
SupplierRMANum = srma.SupplierRMANumber,
SRMADetailsID = srma.Id,
PONumber = srma.PONumber,
CreatedOn = srma.CreatedOn,
SupplierName = srma.SupplierName,
SRMAStatus = srma.StatusName,
Status = srma.Status,
suppliersOrderNumber = srma.suppliersOrderNumber,
PODate = srma.PODate,
Sum = srma.Sum,
TrackingNumber = srma.TrackingNumber,
ActualAmount = srma.ActualAmount
}).ToList();
I just want to get Status value of first record. How do I do it?

Linq left join and count - How To

I have the following Linq expression:
var employeeTypes = from t in DbContext.Set<SetupEmployeeType>().AsNoTracking()
join emp in DbContext.Set<Employee>().AsNoTracking() on t.EmployeeTypeId equals emp.EmployeeTypeId into employee
from subemp in employee.DefaultIfEmpty()
where t.MasterEntity == masterEntity
select new Model.SetupEmployeeTypeModel()
{
EmployeeTypeId = t.EmployeeTypeId,
Description = t.Description,
AllowProbation = t.AllowProbation,
IsActive = t.IsActive,
TotalEmployee = (subemp == null ? 0 : subemp.Count)
};
I need to set TotalEmployee property of my custom model.
So if there is no EmployeeTypeId associated to any Employee then TotalEmployee should be 0, else should be the Count of Employees.
Any clue how to do this?
If i may not wrong then consider using a subquery, like so -
var q = from empType in DbContext.Set<SetupEmployeeType>().AsNoTracking()
let empCount =
(
from emp in DbContext.Set<Employee>().AsNoTracking()
where empType.EmployeeTypeId == emp.EmployeeTypeId
select emp
).Count()
select new Model.SetupEmployeeTypeModel()
{
EmployeeTypeId = empType.EmployeeTypeId,
Description = empType.Description,
AllowProbation = empType.AllowProbation,
IsActive = empType.IsActive,
TotalEmployee = empCount
};
Using Group by.
var q = from empType in DbContext.Set<SetupEmployeeType>().AsNoTracking()
join empCnt in
(
from emp in DbContext.Set<Employee>().AsNoTracking()
group emp by emp.EmployeeTypeId into grp
select new { EmployeeTypeId = grp.Key, TotalEmp = grp.Count()}
) on empType.EmployeeTypeId equals empCnt.EmployeeTypeId into employees
from subemp in employees.DefaultIfEmpty()
where t.MasterEntity == masterEntity
select new Model.SetupEmployeeTypeModel()
{
EmployeeTypeId = empType.EmployeeTypeId,
Description = empType.Description,
AllowProbation = empType.AllowProbation,
IsActive = empType.IsActive,
TotalEmployee = subemp.TotalEmp
};
I came up with the following solution:
var employeeTypes = from t in DbContext.Set<SetupEmployeeType>().AsNoTracking()
join empg in
(
from emp in DbContext.Set<Employee>().AsNoTracking()
group emp by emp.EmployeeTypeId into g
select new { EmployeeTypeId = g.Key, Total = g.Count() }
) on t.EmployeeTypeId equals empg.EmployeeTypeId into employee
from subemp in employee.DefaultIfEmpty()
where t.MasterEntity == masterEntity
select new Model.SetupEmployeeTypeModel()
{
EmployeeTypeId = t.EmployeeTypeId,
Description = t.Description,
AllowProbation = t.AllowProbation,
IsActive = t.IsActive,
TotalEmployee = subemp.Total
};

How to select Max StartDate in Linq

I want to only get out the max StartDate, its multiples of dates with the same CustomNumber
Any suggestions?
My simplified code
from Cus in Customers
where Cus.CustomNumber == 2
group Cus by new
{ Cus.Name,Cus.City,Cus.StartDate}
into grp
select new
{
Name = grp.Key.Name,
City = grp.Key.City,
StartDate = grp.Key.StartDate,
//I have tried, but it doesnt work for me
//StartDate = grp.Max(Cus=> grp.Key.StartDate)
}
try below code
StartDate = grp.Max(x => x.StartDate)
You could try this one:
var result = from Cus in Customers
where Cus.CustomNumber == 2
group Cus by new
{ Cus.Name, Cus.StartDate}
into grp
select new
{
Name = grp.Key.Name,
StartDate = grp.Max(x=>x.StartDate)
};
Using grp you have access to the random group you create in your linq query, then using the extension method called Max you get the maximum StartDate in your group.
UPDATE
Since now you have a join before the grouping, you have to change your code to the following one:
var result = from res in
(from customer in Customers
join house in Houses
on customer.CustomNumber equals house.CustomNumber
where customer.CustomNumber == 2
select new { Name = customer.Name, StartDate = house.StartDate })
group res by res.Name into grp
select new { Name = grp.Key, StartDate = grp.Max(x=>x.StartDate) };
UPDATE #2
If you want you get both the customer's Name and City in your result, you have to use the following code:
var result = from res in
(from customer in Customers
join house in Houses
on customer.CustomNumber equals house.CustomNumber
where customer.CustomNumber == 2
select new { Name = customer.Name, City = customer.Name, StartDate = house.StartDate })
group res by new { res.Name, res.City } into grp
select new
{
Name = grp.Key.Name,
City = grp.Key.City,
StartDate = grp.Max(x=>x.StartDate)
};

Linq to SQL using group By, and order by count

This is mysql query:
SELECT count(PVersion), PVersion
FROM [Products].[dbo].[Active_Details]
group by PVersion
order by count(PVersion);
What will be its LINQ to SQL.
Try this:
var product =
from p in yourContext.Active_Details
group p by p.PVersion into pgroup
let count = pgroup.Count()
orderby count
select new { Count = count, PVersion = pgroup.Key };
SELECT count(ProductVersion), ProductVersion , ProductID , SubProductID
FROM [do-not-delete-accounts].[dbo].[Activation_Details]
group by ProductVersion,ProductID,SubProductID
order by count(ProductVersion);
var query =
from p in yourContext.Activation_Details
group p by new
{
ProductVersion = p.ProductVersion,
ProductID = p.ProductID,
SubProductID = p.SubProductID
}
into pgroup
let count = pgroup.Count()
orderby count
select new
{
Count = count,
ProductVersion = pgroup.Key.ProductVersion,
ProductID = pgroup.Key.ProductID,
SubProductID = pgroup.Key.SubProductID
};
Should be a group into:
var product = (
from p in yourContext.Active_Details
group p by p.PVersion into pgroup
select new { VersionCount= pgroup.Count(), pgroup.Key }
).OrderBy(x=>x.VersionCount);
Here is a MSDN Resource with examples

Categories

Resources