嵌套查询

1、嵌套联表 

1.1 Queryable和表 JOIN

//写法1
var queryable=db.Queryable<Order>();
var list=db.Queryable(queryable).LeftJoin<OrderDetails>((o,d)=>o.id==d.orderid).Select(o=>o).ToList();

//写法2
db.Queryable<Order>()
  .Select<Order>()//mergetable之前要有Select
 .MergeTable()//合并成一个表 (MergeTable之前不能有OrderBy)
.LeftJoin<OrderDetails>((o,d)=>o.id==d.orderid).Select(o=>o).ToList();

//5.1.3.41版本只有Where可以不写MergeTable
db.Queryable<Order>().Where(it=>o.id==1)
.LeftJoin<OrderDetails>((o,d)=>o.id==d.orderid).Select(o=>o).ToList();


//匿名对象看标题2

1.2 表和Queryable JOIN

var queryableRight = db.Queryable<OrderItem>().Where(x => x.OrderId > 0);
var list=db.Queryable<Order>().LeftJoin(queryableRight,(o,d)=>o.Id == d.OrderId).Select(o=>o).ToList();

1.3 多个Queryable JOIN

新语法:

 var q11 = db.Queryable<Order>().Where(it => it.Id>1);
 var q22 = db.Queryable<Order>().Where(it => it.Id > 2);
 var q33 = db.Queryable<Order>().Where(it => it.Id > 3);
 
  var list= q11.LeftJoin(q22, (x, y) => x.Id == y.Id)
         .LeftJoin(q33, (x, y, z) => x.Id == z.Id)
         .ToList();

老语法:

最多支持3个queryableJOIN有重载(5.0.6.5支持到4个) F12看重载

var query1 = db.Queryable<Student, School>((st, sc) => new JoinQueryInfos(JoinType.Left,st.SchoolId==sc.Id))
        .Where(st => st.Name == "jack");

var query2 = db.Queryable<DataTestInfo>();

db.Queryable(query1, query2,JoinType.Left, (p1, p2) => p1.Id == p2.Int1).Select<ViewModelStudent>().ToList();


//SELECT * FROM 
         //    (SELECT          [st].[ID],[st].[SchoolId],[st].[Name],[st].[CreateTime] 
              //                  FROM [STudent] st 
                //                Left JOIN [School] sc ON ([st].[SchoolId]=[sc].[Id] )   
                 //               WHERE ( [st].[Name] = @Name0Join0 ))  p1 
               //
             //  LEFT JOIN
               
            // (SELECT          [Int1],[Int2],[String],[Decimal1],[Decimal2],
               //                [Datetime1],[Datetime2],[Image1],[Image2], 
               //               [Guid1],[Guid2],[Money1],[Money2],[Varbinary1],
            //                  [Varbinary2],[Float1],[Float2] FROM [DataTestInfo] )p2   
              
       //     ON ( [p1].[ID] = [p2].[Int1] )

1.4 表和SQL JOIN  

新语法糖  5.0.4.3 preview-05  nuget勾选允许预览版

 //SqlQueryable就是一个Sql转成Queryable
 var list= db.SqlQueryable<Student>("select * from student").Where(it=>it.Id==1).ToPageList(1, 2);

  //具体用例:
 db.Queryable<Order>()
   .LeftJoin(db.SqlQueryable<Custom>("select * from Custom"), (o, i) => o.CustomId == i.Id) 
    .Select(o => o).ToList();
 //SELECT o.* FROM [Order] o Left JOIN (select * from Custom) i ON ( [o].[CustomId] = [i].[Id] )
 
 
//5.1.3.41支持了反过来用
db.SqlQueryable<Custom>("select * from Custom").LeftJoin...

1.5 表和List<T>对象 JOIN

 var queryable = db.Reportable(List<实体>).ToQueryable();
 var list= db.Queryable<Order>()
               .InnerJoin(queryable, (x1, x2) => x1.Id == x2.OrderId)
         .Select((x1, x2) => new { name = x1.Name, id = x1.Id, orderid = x2.OrderId })
         .ToList();

更多用法:https://www.donet5.com/Home/Doc?typeId=2315

2、匿名类型嵌套联表 

//单个匿名对象JOIN
//注意: 如果有OrderBy请写在MergeTable后面
db.Queryable<Order>()
    .Select(it => new { id = it.Id })//匿名对象
    .MergeTable()//合并成新表 MergeTable 和 OrderItem 进行JOIN
    .LeftJoin<OrderItem>((x, y) => x.id == y.ItemId) //最后一个表不能是匿名对象
    .ToList();
    
//技巧:如果匿名对象在右边  可以把 LeftJoin 换成 RightJoin 变相就实现了 
//多个匿名对象JOIN看下面
        
//多个匿名对象Join 
//注意: 如果有OrderBy请写在MergeTable后面   
db.Queryable<Order>()
    .Select(it => new { id = it.Id })//匿名对象
    .MergeTable()//合并 
    .LeftJoin<OrderItem>((x, y) => x.id == y.ItemId) //联表
    .Select((x, y) => new {xid=x.id,yid=y.ItemId})//在次转成匿名对象
    .ToList(); 


//老版本用法
var query1 = db.Queryable<Order, OrderItem>((o, i) => new JoinQueryInfos(
              JoinType.Left, o.Id == i.OrderId
            ))
            .Where(o => o.Name == "jack");

            var query2 = db.Queryable<Custom>()
            //转成Object
            .Select<object>(it=>new { 
               id=1
            });
            var list3=db.Queryable(query1, query2,JoinType.Left, 
                 //query2是匿名对象所以p2.id用字符串实现
                (p1, p2) => p1.CustomId == SqlFunc.MappingColumn(default(int),"p2.id"))
                .Select<ViewOrder>().ToList();

3、多合一查询

一般多表查询后 动态使用搜索条件和排序 需要使用 st sc等前缀,多表合成一后变成了单表查询 所以都不需要加别名了

var pageJoin = db.Queryable<Student, School>((st, sc) => new JoinQueryInfos(JoinType.Left,st.SchoolId==sc.Id))
    .Select((st,sc) => new
    { 
        id = st.Id,
        name = sc.Name
    })
    .MergeTable() //在mergetale之前不能有排序 分页 skip take操作,之后可以
    .Where(it=>it.id==1).OrderBy("name asc").ToList();
SELECT * FROM 

               (SELECT  
                    [st].[Id] AS [id] , [sc].[Name] AS [name]  
                    FROM [Student] st Left 
                    JOIN [School] sc ON ( [st].[SchoolId] = [sc].[Id] )  ) MergeTable--将结果变成一个表  
           
            WHERE ( [id] = @id0 )ORDER BY name asc

4、一合一嵌套

//三种写法结果一样的

//写法1:
var subQuery=db.Queryable<Order>().Select(it=>new xxx{....});
var list=db.Queryable(subQuery).ToList();

//写法2:
var list=db.Queryable<Order>().SelectMergeTable(it=>new xxx{....}).ToList();//高版本可以用这个(WithTempQuery)

//写法3:
var list=db.Queryable<Order>().Select(it=>new xxx{....}).MergeTable().ToList();//也可以分开写

Sql代码如下:

SELECT t.* FROM  (SELECT [Id],[Name],[Price],[CreateTime],[CustomId] FROM [Order] ) t

5、跨库特殊情况

QueryableAttr 

db.QuryableWithAttr<T>().LeftJoin<T2>(...).ToList();//切换成库不会改主表名 (leftJoin部分一样的)

AsWithAttr() 

db.Quryable<T>().AsWithAttr().LeftJoin<T2>(...).ToList();//不是当前库改表名不切换库  (leftJoin部分一样的)

下面一些特别用例要改AsWithAttr

var q1=db.Queryable<UnitNClobTest>().AsWithAttr(); 
var q2=db.Queryable<UnitNClobTest>().AsWithAttr(); 
//如果用QuryableWithAttr他们如果有切换库操作 表名也不会变,所以要用AsWithAttr强势变表名
db.UnionAll(q1, q2).ToList();


关闭
果糖网