簡體   English   中英

如何將此查詢轉換為 linq?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM