How does it work?

AdaptiveLINQ transform a LINQ expression to another LINQ expression.
Data is never handled by AdaptiveLINQ.

AdaptiveLINQ implement a LINQProvider capable of detecting properties used by the query and then adapt the query for the underlying LINQProvider (like Entity Framework).

The adaptee form of a .QueryByCube() use the .GroupBy() LINQ operator.

The part corresponding to .QueryByCube() in a query expression will be transformed to:

.GroupBy(
    item => new { /* key selector */
        Dimension1 = Dimension1Function(item),
        Dimension2 = Dimension2Function(item),
        ...
    },
    (groupKey, groupItems) => new { /* result selector */
        Dimension1 = groupKey.Dimension1,
        Dimension2 = groupKey.Dimension2,
        ...
        Measure1 = Measure1Function(groupItems),
        Measure2 = Measure2Function(groupItems),
        ...
    })
QueryByCube acts as a dynamic group by where key selector is determined at runtime.

Sample

The query top five customer concerning the product category Bikes will be written:

myDataSet.QueryByCube(mySalesCube)
    .Where(item => item.ProductCategory == "Bikes")
    .OrderByDescending(item => item.TotalSales)
    .Take(5)
    .Select(item => item.Customer);

AdaptiveLINQ detect the use of dimensions ProductCategory and Customer and the use of measure TotalSales. The adaptee query will be written:

myDataSet.GroupBy(
    item => new { /* key selector */
        ProductCategory = item.SpecialOfferProduct.Product.ProductSubcategory.ProductCategory.Name,
        Customer = item.SalesOrderHeader.Customer.Person.LastName
    },
    (groupKey, groupItems) => new { /* result selector */
        ProductCategory = groupKey.ProductCategory,
        Customer = groupKey.Customer,
        TotalSales = groupItems.Sum(i => i.LineTotal)
    }).Where(item => item.ProductCategory == "Bikes")
    .OrderByDescending(item => item.TotalSales)
    .Take(5)
    .Select(item => item.Customer);