This project is read-only.
I made some rather ad hoc decisions in the design of the Linq queries to be supported.

First of all I decided that the most basic type of query
    db.SomeTable.Where(t => t.SomeColumn == "SomeValue").Select(t => t.SomeOtherColumn)
Should translate to:
    EVALUATE
    CALCULATETABLE (
        SUMMARIZE ( SomeTable, SomeTable[SomeOtherColumn] ),
        SomeTable[SomeColumn]
            = "SomeValue"
    )
This choice was made due to the fact that in our usage this is the most common query in tabular by far. So it seemed to be good choice to translate it from the simplest Linq query.

On the other hand this means that we won't make the implicit GROUP BY in SUMMARIZE explicit in Linq, and consequently we won't be able to support GroupBy on tabular Linq queries without confusion.


A similar arbitrary choice was mad with joins that we would rather have relationships defined in the mapped context as table mapped properties than having to do explicit joins. Also since in most cases we can refer to related tables in DAX without explicitly joining. However in linq we still need the pseudo SelectMany-s to have identifiers in queries, see examples in Supported Queries
And last there are the methods extensions accepting a boolean.
These are used actually as boolean expressions in the translation, for example:
    sales.SalesAmount.Sum(c.FirstName == "Tony")
translates to
    CALCULATE (
            SUM ( 'Internet Sales'[Sales Amount] ),
            'Customer'[First Name]
                = "Tony"
        )
This behaviour again is due to the fact that the conditions in CALCULATE is not restricted to the table we are selecting from, so this seems to be the most readable way to express things.

I chose to use OleDb** as the underlying provider, so that we can leverage the string based Item in OleDbDataReader. Also it does not require the Microsoft.AnalisysServices.dll to be installed on the machine. (Although the current schema generation example uses ADOMD to get the schema from the server, but that is not necessary for the provider itself.

On the other hand this means that probably we can't use parameters, but I considered SQL injection risk rather small as tabular is read only, and not SQL based, but ADOMD does not seem to do connection pooling which seems to be an obstacle for applications that would use a LINQ provider.

A future enhancement could be to abstract away from OleDb and make the provider configurable, to use different strategies (parameters or no parameters).

Last edited Apr 28, 2014 at 12:16 PM by LinqToDax, version 4