Equivalent LINQ to SQL code - c#

Am new to this here is my T-SQL
SELECT category.id, category.name,COUNT(job.id) AS countofjobs
FROM category
LEFT OUTER JOIN job ON category.id = job.categoryid AND job.active=1
WHERE category.featured=1
GROUP BY category.id, category.name
ORDER BY category.name
what will be the equivalent LINQ to SQL code? any help will be appreciated
Sorry I forgot to mention that there is no relationship database side, tables have no association at all defined in db, thats the main issue, this is really just sample sql to see how I can write Link to SQL for T-SQL that requires: Left outer join, Count of outer join table records and sorting

var result = dataContext.Categories
.Where(c => c.Featured)
.OrderBy(c => c.Name)
.Select(c => new { c.Id,
c.Name,
CountOfJobs = c.Jobs.Count(j => j.Active) };
Alternatively:
var result = from c in dataContext.Categories
where c.Featured
orderby c.Name
select new { c.Id, c.Name, CountOfJobs = c.Jobs.Count(j => j.Active) };

Since you don't have relationships:
var result = from c in dataContext.Categories
where c.Featured
orderby c.Name
select new {
c.Id,
c.Name,
CountOfJobs = dataContext.Jobs.Count(j => j.categoryId == c.Id && j.Active)
};

Related

sql query do in subquery in LINQ

below is my SQL query
SELECT
p.Name
, p.DisplayName
, (
SELECT COUNT(*)
FROM LicenseActivations la
WHERE la.ProductId=p.Id
AND la.AccountId='QWNjb3VudDo2N2YyMTcwMC0xMWZlLTExZWItYjNkMS0yN2U1Mjk0MGVhYmU='
) AS COUNT
FROM [Products] p
GROUP BY p.Name, p.DisplayName, p.id;
here I am using two tables 1.Products 2.LicenseActivations, I need to form LINQ, Can anyone help me out with this one
In Linq you seldom need joins. With a proper database design with relations established, Linq navigation properties does the job (which are generated automatically by the tools for you):
var list = from p in _DbContext.Products
select new {
p.Name,
p.DisplayName,
Count = p.LicenseActivations.Count(x => x.AccountId=="QWNjb3VudDo2N2YyMTcwMC0xMWZlLTExZWItYjNkMS0yN2U1Mjk0MGVhYmU=")
};
is the corresponding Linq query of your SQL (ToList() is optional).
EDIT: If you don't have proper relations in your database, then:
var list = from p in _DbContext.Products
select new {
p.Name,
p.DisplayName,
Count = _DbContext.LicenseActivations
.Count(x => x.ProductId == p.Id &&
x.AccountId=="QWNjb3VudDo2N2YyMTcwMC0xMWZlLTExZWItYjNkMS0yN2U1Mjk0MGVhYmU=")
};

Linq query for top parents by number of childs, including this number

In my model, there are entities Article and Tag in many-to-many relation through table ArticleTag.
I want to select "trending tags" - tags with most articles in last X days, and I want this count too.
Basically, I need help creating EF Linq query equivalent to this SQL query, with ideal result being Dictionary<Tag, int>
SELECT TOP 50
t.Id, t.Name, count(*)
FROM ArticleTag at
JOIN Article a ON a.Id = at.ArticleId
JOIN Tag t ON t.Id = at.TagId
WHERE a.DateCreated > '2019-10-01'
GROUP BY t.Id, t.Name
ORDER BY count(*) DESC
Can this be done without having ArticleTag as DbSet in DbContext (since it is not really an entity, and I dont need it besides this query).
You have to use navigation properties for this query and do not need to know anything about ArticleTag table.
var query =
from a in ctx.Articles
from t in a.Tags
where a.DateCreated > someDate
group t by new { t.Id, t.Name } into g
orderby g.Count() descending
select new
{
g.Key.Id,
g.Key.Name,
Count = g.Count()
};
var result = query
.Take(50)
.ToDictionary(x => new Tag { Id = x.Id, Name = x.Name }, x => x.Count);

How to convert LINQ query syntax with joins, groups and inline query to LINQ method syntax

I need to convert the following query in SQL to LINQ using the method syntax, but I'm getting confused when I try to include the inline query, joins and groupings:
SELECT CL.*, CB.*, CD.*, CC.*, CS.*
FROM clients AS CL
INNER JOIN (
SELECT A.client_id, SUM(A.amount) AS balance
FROM accounts AS A
WHERE A.account_id = 1
GROUP BY A.client_id
HAVING (SUM(A.amount) > 0.015) OR (SUM(A.amount) < -0.015)
) AS CB ON CL.client_id = CB.client_id
INNER JOIN client_details AS CD ON (CL.client_id = CD.client_id) AND (CL.audit_id = CD.audit_id)
LEFT JOIN client_categories AS CC ON CD.client_category_id = CC.client_category_id
LEFT JOIN statuses AS CS ON CD.status_id = CS.status_id
I did get the GROUP BY and HAVING portions working independently of the overall query, but I have not been able to merge this with the rest as an inline query (though I've tried .Any and other LINQ methods):
.Where(a => a.AccountId == 1)
.GroupBy(a => new { a.ClientId })
.Where(ag => ag.Sum(a => a.Amount) > 0.015M || ag.Sum(a => a.Amount) < -0.015M)
.Select(ag => new { Id = ag.Key.ClientId, Balance = ag.Sum(a => a.Amount) })
I have managed to convert it to LINQ using the query syntax, which works perfectly for me, but I need it in the method (Lambda) syntax:
var clients = from c in _context.Clients
join cb in (from a in _context.Accounts
where a.AccountId == 1
group a by new { Id = a.ClientId } into g
where g.Sum(gs => gs.Amount) > 0.015M || g.Sum(gs => gs.Amount) < -0.015M
select new { g.Key.Id, Balance = g.Sum(gs => gs.Amount) }) on c.Id equals cb.Id
join cd in _context.ClientDetails on new { c.Id, c.AuditId } equals new { cd.Id, cd.AuditId }
join cc in _context.ClientCategories on cd.ClientCategoryId equals cc.Id into ccj
from cc in ccj.DefaultIfEmpty()
join cs in _context.Statuses on cd.StatusId equals cs.Id into csj
from cs in csj.DefaultIfEmpty()
select new Client(c, cb.Balance, new ClientDetails(cd, cc, cs));
Any help greatly appreciated.
It appears that LinqPad offers the solution. Run the LINQ query syntax against your database and, when it finishes, click the Lambda symbol at the bottom of the page to see the method syntax:
LinqPad Window
Thanks LinqPad!

Trouble translating SQL query to LINQ with join and having count

I have this SQL query that I need to translate to LINQ.
SELECT p.productId, p.name, COUNT(np.ID) AS 'salesLast70', p.quantity
FROM Products p
LEFT JOIN NOrderProducts np
ON np.product_id = p.productId
WHERE np.date_picked > DATEADD(DAY, -70, getdate())
GROUP BY p.productId, p.name, p.quantity
HAVING COUNT(np.ID) < p.quantity
Right now I have the following LINQ query.
var date70 = DateTime.Now.AddDays(-70).Date;
var almostOutOfStockProducts = from p in db.Products
join np in db.NOrderProducts on p.productId equals np.product_id
where np.date_picked > date70
group np by np.ID into npGrp
where npGrp.Count() < p.quantity
select p;
But p cannot be resolved at the end of the LINQ query at > p.quantity and select p.
I'm sure I am missing something in my LINQ query but I cannot seem to find exactly how to fix it.
EDIT:
I ended up using db.Database.SqlQuery(); with the raw query.
To achieve what you want you have to lift the quantity, name from the product up into the group by. You are doing this in your sql version with the clause GROUP BY p.productId, p.name, p.quantity but you are not doing this in your linq version.
An example would be to do:
var almostOutOfStockProducts = db.Products.Join(db.NOrderProducts, p => p.productId, np => np.product_id, (p, np) => new { p, np })
.Where(x => x.np.date_picked > date70)
.GroupBy(x => new { Quantity = x.p.quantity, Name = x.p.name, ProductId = x.p.productId})
.Where(x => x.Count() < x.Key.Quantity)
.Select(x => new {ProductId = x.Key.ProductId, Quantity = x.Key.Quantity, Name = x.Key.Name});
In the GroupBy I am bringing through the product id, quantity and name from the product into an anonymous type. This then becomes the key so I can use it in the Where clause and also in the Select at the end.

Replacing SQL join and group query with linq query in Entity Framework

I have an existing SQL query:
select
mn.accountid, sum(u.peak), sum(u.text), sum(u.datagig),
sum(p.minutesallowed), sum(p.messagesallowed), sum(p.dataallowed)
from
usage u
inner join
mtn mn on u.mtnid = mn.Id
inner join
[plan] p on p.id = mn.planid
group by
mn.accountid
Using Entity Framework, I'm working on converting this to linq, and I've gotten this far:
var tots = from u in currentUsage
join mn in mtns on u.mtnId equals mn.Id
join p in plans on mn.PlanId equals p.Id
group u by u.AccountId into g
select new MainUsageResults
{
TotalPeakMinutes = g.Sum(x => x.Peak),
TotalData = g.Sum(x => x.DataGig),
TotalMessaging = g.Sum(x => x.Text),
TotalAllowedMinutes = g.Sum(x => ???) ,
TotalAllowedMessages = g.Sum(x => ???) ,
TotalAllowedData = g.Sum(x => ???)
};
I can't figure out how to sum up the data that is on the joined tables. In SQL one would have the whole set of columns available in a join, but it doesn't seem to be the case here. How do I get the sum of the columns on the joined tables in this example?
Thanks to #3-14159265358979323846264, a real nice example can be found here

Categories