Como você estende Linq para SQL?
-
09-06-2019 - |
Pergunta
No ano passado, Scott Guthrie afirmou “Na verdade, você pode substituir o SQL bruto que o LINQ to SQL usa se quiser controle absoluto sobre o SQL executado”, mas não consigo encontrar documentação descrevendo um método de extensibilidade.
Gostaria de modificar a seguinte consulta LINQ to SQL:
using (NorthwindContext northwind = new NorthwindContext ()) { var q = from row in northwind.Customers let orderCount = row.Orders.Count () select new { row.ContactName, orderCount }; }
O que resulta no seguinte TSQL:
SELECT [t0].[ContactName], ( SELECT COUNT(*) FROM [dbo].[Orders] AS [t1] WHERE [t1].[CustomerID] = [t0].[CustomerID] ) AS [orderCount] FROM [dbo].[Customers] AS [t0]
Para:
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 }; }
Qual seria resultar no seguinte 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))
Usando:
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; }
E
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; } }
Usando algum tipo de extensibilidade do LINQ to SQL, diferente de Este.Alguma ideia?
Solução
A capacidade de alterar o provedor subjacente e, assim, modificar o SQL não foi o corte final no LINQ to SQL.
Outras dicas
O blog de Matt Warren tem tudo que você precisa para isso:
Você deseja traduzir uma árvore de expressão em SQL...Você precisa implementar seu próprio IQueryProvider
DataContext x = novo DataContext;
//Algo assim, talvez?
var a = x.Where().with()...etc
vamos ter um controle muito mais preciso sobre o sql.