union 分頁/group/join 複雜查詢(.net core/framework)

union 分頁/group/join 複雜查詢(.net core/framework)

unoin是一個比較特殊的查詢,對union進行分頁,關聯,分組需要在最外面包裝一層,如果對union結果再進行其它關聯,分組,複雜度直線上升,解決此問題

  1. 安裝nuget包:CRL
  2. using CRL;

以下爲默認數據源實現

如果使用ef core和ado.net 見:Data/EFTest · hubroxxl/CRL - 碼雲 - 開源中國 (gitee.com)

定義數據源

var builder = DBConfigRegister.GetInstance();
builder.RegisterDBAccessBuild(dbLocation =>
        {
            return new DBAccessBuild(DBType.MSSQL, "server=.;database=testDb; uid=sa;pwd=123;");
        });

定義對象管理器

public class ProductRepository:BaseProvider<ProductData>
{
    public static ProductRepository Instance
        {
            get { return  new ProductRepository(); }
        }
}

通過GetLambdaQuery方法創建ILambdaQuery

ILambdaQuery能實現子查詢和嵌套查詢,只要符合T-SQL語義邏輯,可以使用ILambdaQueryResultSelect無限疊加

如:

  • join後group
  • join後再join
  • group後再join
  • join一個group結果
  • join一個union結果
  • 對union進行group再join
  • ...

簡單的union

var query = ProductRepository.Instance.GetLambdaQuery().Where(b => b.Id < 200);
            var query2 = query.CreateQuery<Code.Order>().Where(b => b.Id < 200);
            var view1 = query.Select(b => new { a1 = b.Id, a2 = b.ProductName });
            var view2 = query2.Select(b => new { a1 = b.Id, a2 = b.Remark });
            var result = view1.Union(view2).OrderBy(b => b.a1).OrderBy(b => b.a2, false).ToList();
            var sql = query.PrintQuery();

生成SQL爲

select t1.[Id] as a1,t1.[ProductName1] as a2 from [ProductData] t1  with (nolock)  where (t1.[Id]<'200')
 union all
select t2.[Id] as a1,t2.[Remark] as a2 from [OrderProduct] t2  with (nolock)  where (t2.[Id]<'200')
  order by [a1] desc,[a2] asc

對union進行分頁

var query = ProductRepository.Instance.GetLambdaQuery().Where(b => b.Id < 200);
            query.Take(10);
            var query2 = query.CreateQuery<Code.Order>().Where(b => b.Id < 200).Take(5);
            var view1 = query.Select(b => new { a1 = b.Id, a2 = b.ProductName });
            var view2 = query2.Select(b => new { a1 = b.Id, a2 = b.Remark });
            var union = view1.Union(view2).OrderBy(b => b.a1).OrderBy(b => b.a2, false);
            union.UnionPage(15, 1);//分頁參數
            var result = union.ToList();
            var sql = query.PrintQuery();

生成SQL爲

SELECT * FROM (select a1,a2,ROW_NUMBER() OVER ( Order by [a1] desc,[a2] asc ) AS RowNumber  from (select top 10 t1.[Id] as a1,t1.[ProductName1] as a2 from [ProductData] t1  with (nolock)  where (t1.[Id]<200)
 union all 
select top 5 t2.[Id] as a1,t2.[Remark] as a2 from [OrderProduct] t2  with (nolock)  where (t2.[Id]<200)) tu) T WHERE T.RowNumber BETWEEN 1 AND 15 order by RowNumber

union後再join

var query = ProductRepository.Instance.GetLambdaQuery().Where(b => b.Id < 200);
            query.Take(10);
            var query2 = query.CreateQuery<Code.Order>().Where(b => b.Id < 200).Take(5);
            var view1 = query.Select(b => new { a1 = b.Id, a2 = b.ProductName });
            var view2 = query2.Select(b => new { a1 = b.Id, a2 = b.Remark });
            var union = view2.Union(view1).OrderBy(b => b.a1).OrderBy(b => b.a2, false);
            var join = query.Join(union, (a, b) => a.Id == b.a1).Select((a, b) => new { a.Id, b.a2 });//join
            var result = join.ToList();
            var sql = query.PrintQuery();

生成SQL爲

select top 10 t1.[Id],t3.[a2] as a2 from [ProductData] t1  with (nolock)  Inner join (select top 5 t2.[Id] as a1,t2.[Remark] as a2 from [OrderProduct] t2  with (nolock)  where (t2.[Id]<'200')
 union all 
select top 10 t1.[Id] as a1,t1.[ProductName1] as a2 from [ProductData] t1  with (nolock)  where (t1.[Id]<'200')
  order by [a1] desc,[a2] asc) t3  on t1.[Id]=t3.a1 where (t1.[Id]<'200')

union後再group

var query = ProductRepository.Instance.GetLambdaQuery().Where(b => b.Id < 200);
            var query2 = query.CreateQuery<Code.Order>().Where(b => b.Id < 200);
            var view1 = query.Select(b => new { a1 = b.Id, a2 = b.ProductName });
            var view2 = query2.Select(b => new { a1 = b.Id, a2 = b.Remark });
            var union = view1.Union(view2).OrderBy(b => b.a2, false);
            var group = union.UnionGroupBy(b => b.a2);//group
            var result = group.Select(b => new { b.a2 }).ToList();
            var sql = query.PrintQuery();

生成SQL爲

select a2 from (select t1.[Id] as a1,t1.[ProductName1] as a2 from [ProductData] t1  with (nolock)  where (t1.[Id]<'200')
 union all
select t2.[Id] as a1,t2.[Remark] as a2 from [OrderProduct] t2  with (nolock)  where (t2.[Id]<'200')) tu group by a2
  order by [a2] asc

源碼示例參考

Data/QueryTest/test · hubroxxl/CRL - 碼雲 - 開源中國 (gitee.com)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章