8
votes

Comment créer une méthode qui prend en charge la traduction à SQL?

Je voulais utiliser une méthode que j'ai créée dans une requête Coz, j'ai besoin d'implémenter un type particulier de filtre ... xxx pré>

mais je reçois le: p>

"Méthode 'Boolean Satisfyfilter (System.String, System.String)' n'a pas de traduction prise en charge sur SQL." P>

erreur p>

Ma méthode est la suivante: P>

public bool Contains(string value)


0 commentaires

6 Réponses :


4
votes

Une réponse simple est vous ne pouvez pas strong>. Le traducteur LINQ to SQL ne reconnaît que certaines des méthodes standard .NET et qu'il n'y a aucun moyen que vous puissiez ajouter d'autres.

  • Si vous avez besoin de quelque chose comme ça, vous devrez créer explicitement une arborescence d'expression (à utiliser comme corps de l'expression de Lambda). Une manière directe de cela consiste à utiliser des méthodes de la classe code> code>, mais elle peut être simplifiée beaucoup. p> li>

  • Peut-être la meilleure option consiste à utiliser le Projet Linqkit . Il permet d'appeler d'autres EM> Lambda Expressions em> (pas tout à fait la méthode, mais proche). Il fournit une méthode d'extension asexpandable code> asexpandable qui vous permet d'écrire: p>

    Expression<Func<Purchase, bool>> customFunction = ...
    var data = new MyDataContext();
    var query =
      from c in data.Purchases.AsExpandable()
      where customFunction.Compile()(c)
      select c.Name;
    
  • Autre alternative qui est en plus de détails discutés par d'autres personnes pour mettre en œuvre la fonctionnalité en tant que fonction définie par l'utilisateur SQL. Ensuite, vous pouvez faire glisser la fonction dans votre contexte de données et appeler la fonction de la requête. Le traducteur insérera simplement un appel à votre fonction SQL. P> li> ul> p>


0 commentaires

1
votes

Si vous pouvez mapper cela sur un UDF, vous pouvez faire glisser le UDF dans le contexte de données. Lorsqu'il est accédé via le contexte de données LINQ-TO-SQL peut faire la traduction.

Si vous ne faites que filtrer un iquérirable, vous pouvez écrire une méthode qui utilise simplement où (retourner une nouvelle iquéryable) qui peut bien fonctionner.

Si vous avez besoin de tasse de plus, vous devrez peut-être vous gâcher manuellement avec des arbres d'expression.


0 commentaires

1
votes

Vous faites deux choses:

  1. Créez une fonction scalaire définie par l'utilisateur dans SQL: http://msdn.microsoft. COM / EN-US / Bibliothèque / BB386973.ASPX
  2. Appelez-le comme vous le souhaitez à Linq à SQL: http: // msdn. microsoft.com/en-us/library/bb399416.aspx

0 commentaires

0
votes

Le moyen le plus simple de le faire est de déterminer comment convertir votre fonction «satisfontrice» en une série de commandes LINQ avec une traduction acceptée. J'ai bien peur qu'il n'y ait vraiment pas d'autre moyen «facile» d'utiliser votre fonction personnalisée sans filtrer vos 25 millions de clients à un nombre plus important de matérialiser.


0 commentaires

8
votes

Créer une fonction utilisateur sur votre serveur SQL qui correspond à l'équivalent à votre code C #. Dis que cela s'appelait "dbo.satsfilter".

Créer une méthode sur votre remplacement de DataContext, disons que cela ressemble à: xxx

décorer la méthode C # avec [ Fonction] et [paramètre] attributs de sorte qu'il ressemble à quelque chose comme: xxx

isComposable = true signifie que c'est une fonction plutôt qu'une procédure stockée, et peut donc être utilisée dans le cadre d'une requête plus grande.

Vous pouvez désormais utiliser cette méthode du DataContext et elle sera convertie en SQL le cas échéant, ou le C # sera utilisé dans les requêtes étant exécutées en mémoire.

Notez également que si vous vouliez simplement utiliser SQL tout le temps (parfois utile), vous pouvez appeler dans SQL lorsque la méthode est appelée en C # Code: xxx

Ce n'est pas très utile lorsque l'équivalent C # est pratique, car cela signifie un coup de la base de données et une traduction, mais il est utile que la fonction utilisateur dépend de état de la base de données ou est difficile à traduire bien en C #


4 commentaires

Voulez-vous dire que je devrai hériter de la classe DataContext, puis placer la méthode satisfaisesFilter comme une méthode d'instance à l'intérieur? Et alors en tirant sur Linq vers des requêtes SQL, je devrais utiliser ma nouvelle classe héritée à la place.


@RBT Je pense que oui. Cela fait longtemps.


Pouvez-vous s'il vous plaît jeter un coup d'œil à mon problème au lien suivant. J'essaye la même chose mais d'avoir une erreur. Stackoverflow.com/Questtions/37814449/...


Le problème est que si je place cette méthode comme méthode d'instance dans ma classe de contexte de données personnalisée qui hérite d'une classe DataContext, comment puis-je l'utiliser dans ma requête LINQ.



1
votes

bonne solution,

Déclarer des propriétés sur une classe pouvant être traduite pour une exécution de Linq à distance avec microsoft.linq.translations .

Exemples

Paquet Nuget

Source sur Github


0 commentaires