I'm trying get count of rows in another table. I need result count of tbl_result_subject_brand table with brand condution. I have a query for this situation:
SELECT tbl_brand.OID, (SELECT COUNT(*) FROM tbl_result_subject_brand WHERE tbl_result_subject_brand.brand_id = tbl_brand.OID) AS NewsCount FROM tbl_brand
This query is working fine but how can I transform this query to LINQ expression in ASP.NET? Really I dont know how to do it..
using (MuleContext muleContext = new MuleContext())
{
list = (from b in muleContext.tbl_brand
join rsb in muleContext.tbl_result_subject
on new { brandID = rsb.BrandID }
equals new { brandID = b.OID }
select new NetNewsCounts
{
BrandID = b.OID,
ResultCount= ???rsb.COUNT???,
}).ToList();
}
Something like this, I guess.
class Test
{
public void TestMethod()
{
var repo = new Repository();
var result = repo.tbl_brand
.Select(b => new NetNewsCounts()
{
BrandID = b.OID,
ResultCount = repo.tbl_result_subject_brand.Count(rb => rb.brand_id == b.OID)
}).ToList();
}
private class Brand
{
public string OID { get; set; }
}
private class ResultBrand
{
public string brand_id { get; set; }
}
private class Repository
{
public List<Brand> tbl_brand { get; set; }
public List<ResultBrand> tbl_result_subject_brand { get; set; }
}
private class NetNewsCounts
{
public string BrandID { get; set; }
public int ResultCount { get; set; }
}
}
If you are performing a normal join you will only get the results of ids that are on both tables. In case this is really what you wanted then you can simplify it and only query a single table:
var result = muleContext.tbl_result_subject
.GroupBy(i => i.BrandID)
.Select(i => new NetNewsCounts { BrandID = i.Key, ResultCount = g.Count() });
If you want ids that are in tbl_brand
but might not be in tbl_result_subject
then perform a left join similar to this: LINQ - Left Join, Group By, and Count . The projection part is similar to the one above.
You can simplify your query into a group by query:
SELECT OID, COUNT(*)
FROM tbl_result_subject_brand
Group By OID
which can be translated into linq like this:
(from r in muleContext.tbl_result_subject_brand
group r by r.OID into g
select new NetNewsCounts { BrandID = g.Key, ResultCount= g.Count() }).ToList();
write like this
public List<Result> GetCount()
{
using (MuleContext db = new MuleContext())
{
var list = db.tbl_brand.Tolist();
List<Result> GN = new List<Result>();
foreach (var n in list)
{
Result Notif = new Result()
{
OID = n.OID,
ResultCount=db.tbl_result_subject_brand.where(t=>t.brand_id=n.OID)
};
GN.Add(Notif);
}
return GN;
}
}
There are a couple of ways around this, but the simplest is the most direct equivalent. I'm assuming that your actual query requirement is that you get all OID
values with counts - including 0s - of matching rows in the other table.
Here's your source query (reformatted and with some aliases to make it simpler):
SELECT
b.OID,
(
SELECT COUNT(*)
FROM tbl_result_subject_brand rs
WHERE rs.brand_id = b.OID
) AS NewsCount
FROM tbl_brand b
We can do almost exactly the same thing in at least some LINQ ORMs:
using (var ctx = new MuleContext())
{
var query =
from b in ctx.tbl_brand
select new
{
b.OID,
NewsCount = ctx.tbl_result_subject_brand.Count(rs => rs.brand_id == b.OID)
};
var list = query.ToList();
}
This works for me when using Linq2DB, which converts it to an SQL query that is basically identical to your original. Exactly the same structure anyway. Other ORMs might not be so OK with the above format.
The other option is groups and joins. Just be aware that joins are inner by default. You need to use join...into...DefaultIfEmpty
to get a left outer join
equivalent, then handle the missing values. It's a mildly painful process.
This has two forms: group-then-join or join-then-group. The first uses a sub-query to get the counts, then joins to that query to get the values you want:
var rsCounts =
from rs in ctx.tbl_result_subject_brand
group 0 by rs.brand_id into grp
select new { brand_id = grp.Key, NewsCount = (int?)grp.Count() };
var query =
from b in ctx.tbl_brand
join rs in rsCounts on b.OID equals rs.brand_id into rstmp
from rs in rstmp.DefaultIfEmpty()
select new
{
b.OID,
NewsCount = rs.NewsCount ?? 0
};
(You can do it in a single statement. It's harder to figure out what it's doing that way sometimes.)
The other version joins the tables together then groups on the relevant columns. This checks for missing rows using a Sum
instead of Count
:
var query =
from b in ctx.tbl_brand
join rs in ctx.tbl_result_subject_brand on b.OID equals rs.brand_id into rstmp
from rs in rstmp.DefaultIfEmpty()
group (rs.brand_id == null ? 0 : 1) by b.OID into grp
select new
{
OID = grp.Key,
NewsCount = grp.Sum()
};
Not pretty, but it works.
I'd suggest you have a look at what the SQL looks like when you run the above. Sometimes the SQL is a bit weird.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.