2014-06-05 72 views
2

我有一個非常正常的加入,我通過JoinSqlBuilder是否可以使用JoinSqlBuilder進行分頁?

var joinSqlBuilder = new JoinSqlBuilder<ProductWithManufacturer, Product>() 
        .Join<Product, Manufacturer>(sourceColumn: p => p.ManufacturerId, 
               destinationColumn: mf => mf.Id, 
               sourceTableColumnSelection: p => new { ProductId = p.Id, ProductName = p.Name }, 
               destinationTableColumnSelection: m => new { ManufacturerId = m.Id, ManufacturerName = m.Name }) 

當然創建,連接此創建可能會返回大量的行,所以我想用分頁 - 最好是在服務器端。但是,我無法在JoinSqlBuilder中找到任何可以讓我這樣做的東西?我錯過了什麼或JoinSqlBuilder不支持這(尚)?

+1

新的'Limit','Skip'和'Offset' API的[現已](HTTPS ://github.com/ServiceStack/ServiceStack.OrmLite/commit/f45700ef5c62edc28f61261549db1070189913eb)在JoinSqlBuilder中[v4.0.22現在在MyGet上](https://github.com/ServiceStack/ServiceStack/wiki/MyGet) – mythz

+1

@mythz謝謝你,你真是太棒了! :) – wasatz

+0

NP :)讓我知道在論壇中是否有任何問題。 – mythz

回答

3

如果您不使用MS SQL Server,我認爲以下方法可行。

var sql = joinSqlBuilder.ToSql(); 
var data = this.Select<ProductWithManufacturer>(
       q => q.Select(sql) 
         .Limit(skip,rows) 
      ); 

如果您正在使用MS SQL Server,它很可能會炸燬你。我正在努力將類似於此的更優雅的解決方案合併到JoinSqlBuilder中。以下是一個快速而骯髒的方法來完成你想要的。

我創建了以下擴展類:

public static class Extension 
{ 

    private static string ToSqlWithPaging<TResult, TTarget>(
     this JoinSqlBuilder<TResult, TTarget> bldr, 
     string orderColumnName, 
     int limit, 
     int skip) 
    { 
     var sql = bldr.ToSql(); 

     return string.Format(@" 
       SELECT * FROM (
        SELECT ROW_NUMBER() OVER (ORDER BY [{0}]) As RowNum, * 
         FROM (
          {1} 
          )as InnerResult 
         )as RowConstrainedResult 
        WHERE RowNum > {2} AND RowNum <= {3} 
      ", orderColumnName, sql, skip, skip + limit); 
    } 

    public static string ToSqlWithPaging<TResult, TTarget>(
     this JoinSqlBuilder<TResult, TTarget> bldr, 
     Expression<Func<TResult, object>> orderSelector, 
     int limit, 
     int skip) 
    { 

     var member = orderSelector.Body as MemberExpression; 
     if (member == null) 
      throw new ArgumentException(
       "TResult selector refers to a non member." 
       ); 

     var propInfo = member.Member as PropertyInfo; 
     if (propInfo == null) 
      throw new ArgumentException(
       "TResult selector refers to a field, it must be a property." 
       ); 

     var orderSelectorName = propInfo.Name; 

     return ToSqlWithPaging(bldr, orderSelectorName, limit, skip); 
    } 
} 

它的應用如下所示:

List<Entity> GetAllEntities(int limit, int skip) 
{ 
    var bldr = GetJoinSqlBuilderFor<Entity>(); 
    var sql = bldr.ToSqlWithPaging(
        entity => entity.Id, 
        limit, 
        skip); 
    return this.Db.Select<Entity>(sql); 
} 
+0

可悲的是我正在使用MSSQL,所以我不能採取簡單的方法:(儘管你的擴展方法似乎工作得很好,所以我想我現在會使用它:)非常感謝! – wasatz

相關問題