[英]How can transform this query to linq?
我正在嘗試獲取另一個表中的行數。 我需要帶有品牌傳導的 tbl_result_subject_brand 表的結果計數。 我對這種情況有疑問:
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
此查詢工作正常,但如何將此查詢轉換為 ASP.NET 中的 LINQ 表達式? 真的不知道怎么弄..
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();
}
像這樣的東西,我猜。
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; }
}
}
如果您正在執行普通連接,您將只會獲得兩個表上的 id 的結果。 如果這確實是您想要的,那么您可以簡化它並且只查詢一個表:
var result = muleContext.tbl_result_subject
.GroupBy(i => i.BrandID)
.Select(i => new NetNewsCounts { BrandID = i.Key, ResultCount = g.Count() });
如果您想獲得在IDS tbl_brand
,但可能不會在tbl_result_subject
然后執行左連接與此類似: LINQ -左加入,集團通過和Count 。 投影部分與上述類似。
您可以按查詢將查詢簡化為一個組:
SELECT OID, COUNT(*)
FROM tbl_result_subject_brand
Group By OID
可以像這樣翻譯成 linq:
(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();
像這樣寫
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;
}
}
有幾種方法可以解決這個問題,但最簡單的是最直接的等價方法。 我假設您的實際查詢要求是您獲得所有OID
值,其中包含另一個表中匹配行的計數(包括 0)。
這是您的源查詢(重新格式化並帶有一些別名以使其更簡單):
SELECT
b.OID,
(
SELECT COUNT(*)
FROM tbl_result_subject_brand rs
WHERE rs.brand_id = b.OID
) AS NewsCount
FROM tbl_brand b
我們至少可以在一些 LINQ ORM 中做幾乎完全相同的事情:
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();
}
這在使用 Linq2DB 時對我有用,它將其轉換為與原始查詢基本相同的 SQL 查詢。 反正結構完全一樣。 對於上述格式,其他 ORM 可能不太好。
另一個選項是組和連接。 請注意,默認情況下連接是內部的。 您需要使用join...into...DefaultIfEmpty
來獲得等效的left outer join
,然后處理缺失值。 這是一個輕微痛苦的過程。
這有兩種形式:組然后加入或加入然后組。 第一個使用子查詢來獲取計數,然后加入該查詢以獲取您想要的值:
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
};
(您可以在單個語句中完成。有時很難弄清楚它在做什么。)
另一個版本將表連接在一起,然后對相關列進行分組。 這使用Sum
而不是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()
};
不漂亮,但它有效。
我建議你看看運行上面的 SQL 是什么樣的。 有時 SQL 有點奇怪。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.