Comment étendez-vous Linq to SQL?
-
09-06-2019 - |
Question
L'année dernière, Scott Guthrie déclaré & # 8220; Vous pouvez en réalité remplacer le SQL brut utilisé par LINQ to SQL si vous souhaitez un contrôle absolu sur le SQL exécuté & # 8221 ;, mais je ne peux pas trouver de documentation décrivant une méthode d'extensibilité.
Je souhaite modifier la requête LINQ to SQL suivante:
using (NorthwindContext northwind = new NorthwindContext ()) { var q = from row in northwind.Customers let orderCount = row.Orders.Count () select new { row.ContactName, orderCount }; }
Ce qui donne le TSQL suivant:
SELECT [t0].[ContactName], ( SELECT COUNT(*) FROM [dbo].[Orders] AS [t1] WHERE [t1].[CustomerID] = [t0].[CustomerID] ) AS [orderCount] FROM [dbo].[Customers] AS [t0]
À:
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 }; }
Quel aboutirait au TSQL suivant:
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))
Utilisation de:
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; }
Et
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; } }
Utilisation d'un type d'extensibilité LINQ to SQL autre que celui-ci . Des idées?
La solution
La possibilité de changer de fournisseur sous-jacent et donc de modifier le code SQL n’a pas permis la coupe finale dans LINQ to SQL.
Autres conseils
Le blog de Matt Warren a tout ce dont vous avez besoin pour cela:
Vous souhaitez traduire une arborescence d'expression en SQL ... Vous devez implémenter votre propre IQueryProvider
DataContext x = new DataContext;
// Quelque chose comme ça peut-être?
var a = x.Where (). avec () ... etc
vous avez un contrôle beaucoup plus fin sur le sql.