Need a subquery in LINQ - c#

I want to Select all items in this table :
_categoryRepository.Table :
Id Name
1 Birthday
2 Christmas
4 Desktops
6 Notebooks
7 Accessories
9 Cell phones
But, . . I want to exclude any 'Id' from _categoryRepository that match 'EventID' in this table :
_MemberEventRepository.Table
Id MemID EventID
1 1 1
3 1 2
5 1 7
7 4 1
8 4 4
that matches the MemId. So for MemID '1', the results would be :
4 Desktops
6 Notebooks
9 Cell phones
I don't know how to do this in LINQ.
var eventsList = from c in _categoryRepository.Table
join m in _MemberEventRepository.Table on ?????????????
where (m.MemID == currentCustomer)
orderby c.Name
select new MyActiveEvents { Id = c.Id, Name = c.Name };
This the SQL equivalent :
SELECT [Id] ,[Name]
FROM [Category]
WHERE Id NOT IN
(SELECT EventID FROM [Category] c INNER JOIN [MemberEvent] m ON m.[EventID] = c.Id)
Is this possible in LINQ?

Should be something like:
var categories = db.Categories
.Where(c => db.MemberEvents.Count(e => EventID == c.Id) == 0);
Update - using your LINQ-code-fragment:
var eventsList = from c in _categoryRepository.Table
where _MemberEventRepository.Table
.Count(m => m.EventID == c.id) == 0
orderby c.Name
select new MyActiveEvents { Id = c.Id, Name = c.Name }
Instead of Count(...) == 0 it should also be possible to use !Any(...).

Maybe an except would work? I'm not sure which solution will translate into the most efficient sql.
var eventsList = (from c in _categoryRepository.Table
orderby c.Name
select new MyActiveEvents { Id = c.Id, Name = c.Name })
.Except(
from c in _categoryRepository.Table
join m in _MemberEventRepository.Table on c.Id equals m.EventID
where (m.MemID == currentCustomer)
select new MyActiveEvents { Id = c.Id, Name = c.Name });

Related

Linq - Join resultset of 1 query with another table

I have a Compilations table which have the details of employees and their compliances, I am getting the Employees whose ComplaianceStateId is either 6 or 9.
I have to get the employee FullName of these employees from the master tblEmployee table.
Table Name is tblEmployee and Column Name is FullName
EmployeeID is the Common key between these 2 tables tblEmployee and tblEmployeeCompliation
List<Int> employeeIds = new List<int>();
List<string> employeeNames = new List<string>();
employeeIds = EMPDB.tblEmployeeCompliations.Where( e=> e.IsActive == true && (e.ComplianceStateId == 6 || e.ComplianceStateId == 9)).Select( e => e.EmployeeID).Distinct().ToList();
employeeNames = //**//
I have to get the employee FullName of these employees from the master
tblEmployee table
From your requirement, you should select FullName instead of EmployeeID
var result = EMPDB.tblEmployeeCompliations
.Where(e => e.IsActive && (e.ComplianceStateId == 6 || e.ComplianceStateId == 9))
.Select(e => e.FullName).Distinct().ToList();
You need to join tblEmployeeCompliation and tblEmployee based on EmployeeID.
Example:
var employeeNames = EMPDB.tblEmployeeCompliations.Join( EMPDB.tblEmployee,
comp => comp.EmployeeID,
cus => cus.EmployeeID,
(comp, cus) => new { comp, cus })
.Where(e => e.comp.IsActive && (e.comp.ComplianceStateId == 6 || e.comp.ComplianceStateId == 9))
.GroupBy(g=>g.cus.FullName)
.Select(x=>x.Key);
OR
var employeeNames = from comp in EMPDB.tblEmployeeCompliations
join cus in EMPDB.tblEmployee on comp.EmployeeID equals cus.EmployeeID
where comp.IsActive=true && (comp.ComplianceStateId == 6 || comp.ComplianceStateId == 9)
group new { cus, comp } by new { cus.FullName } into g
select g.Key.FullName;
Please read this article: LINQ: Distinct() does not work as expected

SQL ROW_NUMBER() in LINQ Query Syntax

I have this query which I wish to replace with Linq as query syntax:
select
ii.Id, ii.Name as Supplier,
qi.Price1, qi.Price2, qi.Price3,
case when qi.price1 is null then NULL else ROW_NUMBER() OVER(ORDER BY isNull(qi.price1,1000000) ASC) end AS Price1Order,
case when qi.price2 is null then NULL else ROW_NUMBER() OVER(ORDER BY isNull(qi.price2,1000000) ASC) end AS Price2Order,
case when qi.price3 is null then NULL else ROW_NUMBER() OVER(ORDER BY isNull(qi.price3,1000000) ASC) end AS Price3Order
From dbo.InquiryItems ii
left join dbo.quoteItems qi on ii.Id = qi.QuoteItem_InquiryItem
SQL-Query Result:
Id Supplier Price1 Price2 Price3 Price1Order Price2Order Price3Order
1655 Supplier 2 80.00 NULL 40.00 3 NULL 1
1656 Supplier 4 65.00 30.00 42.00 2 1 2
1662 Supplier 1 15.00 35.00 43.00 1 2 3
1670 Supplier 3 250.00 NULL NULL 4 NULL NULL
In C# I need this query as a IQueryable Object. I must filter the query for different parts (one or more) and then group it by Supplier (IdAccount) and SUM the prices. This prices I must rank.
return colQuoteItem = from vQuote in this.vQuoteItemOverviews
where vQuote.IdConstructionStageId == ConstructionStageId
group vQuote by new
{
vQuote.IdAccount
} into g
select new vQuoteItemOverviewSum
{
Id = g.Max(x => x.Id),
Price1Order = null, //Here I need the ROW_NUMBER like in the SQL-Syntax
Price2Order = null, //Here I need the ROW_NUMBER like in the SQL-Syntax
Price3Order = null, //Here I need the ROW_NUMBER like in the SQL-Syntax
price1 = g.Sum(x => x.price1),
price2 = g.Sum(x => x.price2),
price3 = g.Sum(x => x.price3),
}
;
Would this work?
var qi1 = (from qi in quoteItems orderby qi.price1 select new {qi.QuoteItem_InquiryItem}).AsEnumerable().Select((i, index) => new {i.QuoteItem_InquiryItem, Rank = index + 1});
var qi2 = (from qi in quoteItems orderby qi.price2 select new {qi.QuoteItem_InquiryItem}).AsEnumerable().Select((i, index) => new {i.QuoteItem_InquiryItem, Rank = index + 1});
var qi3 = (from qi in quoteItems orderby qi.price3 select new {qi.QuoteItem_InquiryItem}).AsEnumerable().Select((i, index) => new {i.QuoteItem_InquiryItem, Rank = index + 1});
return colQuoteItem = from vQuote in this.vQuoteItemOverviews.AsEnumerable()
where vQuote.IdConstructionStageId == ConstructionStageId
group vQuote by new
{
vQuote.IdAccount
} into g
select new vQuoteItemOverviewSum
{
Id = g.Max(x => x.Id),
Price1Order = qi1.FirstOrDefault(_ => _.IdConstructionStageId == x.Id)?.Rank, //Here i need the ROW_NUMBER like in the SQL-Syntax
Price2Order = qi2.FirstOrDefault(_ => _.IdConstructionStageId == x.Id)?.Rank, //Here i need the ROW_NUMBER like in the SQL-Syntax
Price3Order = qi3.FirstOrDefault(_ => _.IdConstructionStageId == x.Id)?.Rank, //Here i need the ROW_NUMBER like in the SQL-Syntax
price1 = g.Sum(x => x.price1),
price2 = g.Sum(x => x.price2),
price3 = g.Sum(x => x.price3),
}
;

how to convert sql statement to LINQ in c#

how to covert to LINQ :
from p in Product
join c in Catalog on c.Id equals p.CatalogId
join m in Manufacturer on m.Id equals p.ManufacturerId
where p.Active == 1
select new { Name = p.Name, CatalogId = p.CatalogId,
ManufacturerId = p.ManufacturerId, CatalogName = c.Name,
ManufacturerName = m.Name };
help!
Don't try to translate the query literally. In LINQ, you don't need to join entities as long as they already have a relationship because LINQ will automatically use the relationship to join the entities:
So assuming your Product has a Catalog property which in turn has Manufacturer property, you can write your LINQ without joins like this:
from p in Product
where p.Active == 1
select new {
Name = p.Name,
CatalogId = p.CatalogId,
ManufacturerId = p.ManufacturerId,
CatalogName = p.Catalog.Name,
ManufacturerName = p.Manufacturer.Name };
The solution is to build a temp result after the first join and use it as the first sequence in the second join
var result = product.Where(p => p.Active == 1), // 1st sequence
.join(catalog, // 2nd sequence
p => p.CatalogId, // selector from 1st sequence
c => c.Id, // selector from 2nd sequence
(p, c) => // take the elements where the selector match
new {ManufacturerId = p.ManufacturerId,
Name = p.Name,
CatalogId = p.CatalogId,
CatalogName = c.Name}) // result is 1st sequence next join
.Join(Manufacturer, // 2nd sequence 2nd join
r => r.ManufacturerId, // selector result 1st join
m => m.Id, // selector 2nd sequence 2nd join
(r, m) => // two elements where the selectors match
new {Name = r.Name, // build the result object
CatalogId = r.CatalogId,
ManufacturerId = r.ManufacturerId,
CatalogName = r.CatalogName,
ManumfacturerName = r.Name});
Piece of cake ^^
Just call ToString() method of IQueryable will return SQL Representation.
var query = from p in Product
join c in Catalog on c.Id equals p.CatalogId
join m in Manufacturer on m.Id equals p.ManufacturerId
where p.Active == 1;
string sqlQuery = query.ToString(); //SQL Query Saved Here

Linq Getting Customers group by date and then by their type

I am working on generating report for showing customer using LINQ in C#. I want to show no. of customers of each type.
There are 3 types of customer registered, guest and manager. I want to group by customers by registered date and then by type of customer. i.e If today 3 guest, 4 registered and 2 manager are inserted. and tomorrow 4,5 and 6 are registered resp. then report should show Number of customers registerd on the day . separate row for each type.
DATE TYPEOF CUSTOMER COUNT
31-10-2013 GUEST 3
31-10-2013 REGISTERED 4
31-10-2013 MANAGER 2
30-10-2013 GUEST 5
30-10-2013 REGISTERED 10
30-10-2013 MANAGER 3
LIKE THIS .
var subquery = from eat in _customerRepo.Table
group eat by new { yy = eat.CreatedOnUTC.Value.Year, mm = eat.CreatedOnUTC.Value.Month, dd = eat.CreatedOnUTC.Value.Day } into g
select new { Id = g.Min(x => x.Id) };
var query = from c in _customerRepo.Table
join cin in subquery.Distinct() on c.Id equals cin.Id
select c;
By above query I get minimum cutomers registerd on that day
Thanks in advance
var query = _customerRepo.Table
.GroupBy(c => new {Date = c.Date.Date, Type = c.TypeOfCustomer})
.Select(g => new
{
Date = g.Key.Date,
Type = g.Key.Type,
Count = g.Count
}
)
.OrderByDescending (r = r.Date);
var query = from c in _customerRepo.Table
group c by new { c.TypeOfCustomer, c.Date } into g
orderby g.Key.Date descending,
g.Key.TypeOfCustomer == "GUEST" ? 1 :
g.Key.TypeOfCustomer == "REGISTERED" ? 2 : 3
select new {
g.Key.Date,
g.Key.TypeOfCustomer,
Count = g.Count()
};
You can remove second ordering if it's not required for daily results to be in order guest > registered > manager:
var query = from c in _customerRepo.Table
group c by new { c.TypeOfCustomer, c.Date } into g
orderby g.Key.Date descending
select new {
g.Key.Date,
g.Key.TypeOfCustomer,
Count = g.Count()
};

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()
};

Categories

Resources