views:

1899

answers:

4

Last year, Scott Guthrie stated “You can actually override the raw SQL that LINQ to SQL uses if you want absolute control over the SQL executed”, but I can’t find documentation describing an extensibility method.

I would like to modify the following LINQ to SQL query:

using (NorthwindContext northwind = new NorthwindContext ()) {
    var q = from row in northwind.Customers
            let orderCount = row.Orders.Count ()
            select new {
                row.ContactName,
                orderCount
            };
}

Which results in the following TSQL:

SELECT [t0].[ContactName], (
    SELECT COUNT(*)
    FROM [dbo].[Orders] AS [t1]
    WHERE [t1].[CustomerID] = [t0].[CustomerID]
    ) AS [orderCount]
FROM [dbo].[Customers] AS [t0]

To:

using (NorthwindContext northwind = new NorthwindContext ()) {
    var q = from row in northwind.Customers.With (
                        TableHint.NoLock, TableHint.Index (0))
            let orderCount = row.Orders.With (
                        TableHint.HoldLock).Count ()
            select new {
                row.ContactName,
                orderCount
            };
}

Which would result in the following TSQL:

SELECT [t0].[ContactName], (
    SELECT COUNT(*)
    FROM [dbo].[Orders] AS [t1] WITH (HOLDLOCK)
    WHERE [t1].[CustomerID] = [t0].[CustomerID]
    ) AS [orderCount]
FROM [dbo].[Customers] AS [t0] WITH (NOLOCK, INDEX(0))

Using:

public static Table<TEntity> With<TEntity> (
    this Table<TEntity> table,
    params TableHint[] args) where TEntity : class {

    //TODO: implement
    return table;
}
public static EntitySet<TEntity> With<TEntity> (
    this EntitySet<TEntity> entitySet,
    params TableHint[] args) where TEntity : class {

    //TODO: implement
    return entitySet;
}

And

public class TableHint {
    //TODO: implement
    public static TableHint NoLock;
    public static TableHint HoldLock;
    public static TableHint Index (int id) {
        return null;
    }
    public static TableHint Index (string name) {
        return null;
    }
}

Using some type of LINQ to SQL extensibility, other than this one. Any ideas?

A: 

DataContext x = new DataContext;

//Something like this perhaps?

var a = x.Where().with()...etc

let's you have a much finer control over the sql.

Even if this does work, doesn't `var a = x.Where()...` mean that you have already performed a `select` and therefore have records that you should not have queried in the first place?
dboarman
A: 

You want to translate an expression tree into SQL... You need to implement your own IQueryProvider

IQueryProvider Reference
How To

MSDN How To

David B
Seems like the community needs to step up with an open implementation of a query provider for sql expression trees :-)
Joel Martinez
Actually, I would like to _extend_ Linq to SQL's IQueryProvider implementation...
George Tsiokos
+4  A: 

The ability to change the underlying provider and thus modify the SQL did not make the final cut in LINQ to SQL.

DamienG
+1  A: 

Matt Warren's blog has everything you need for that:

http://blogs.msdn.com/mattwar/

KristoferA - Huagati.com