L'import Entity Framework EdmFunction n'est pas reconnue

Tout d'abord, j'avais une question précédente quelque time auparavant, qui, même si elle semble très similaire, n'est PAS le même problème, jetez-y un coup d'oeil: Fonction d'import de SQL Server à l'exception d'exécution Entity Framework

Cette fonction, HammingDistance, fonctionnait bien après avoir créé la fonction scalaire dans SQL Server, puis imscope dans Entity Framework à l'aide du mappage de fonction EDM. J'ai continué à build mon site, fait quelques différences autour du site et de l'EDMX, mais je n'ai pas touché à la fonction et je l'ai gardé en security. Voici la fonction SQL sur le server SQL:

ALTER function [dbo].[HammingDistance] (@first bigint, @second bigint) returns int as begin declare @xor bigint = @first ^ @second; declare @one bigint = 1; declare @diff int = 0; declare @and bigint; while (@xor != 0) begin set @and = @xor & @one; if(@and = @one) begin set @diff = @diff + 1; end set @xor = @xor / 2; end return @diff; end 

Et voici mon code C #:

Déclaration:

 public static class EdmFunctionMapping { [EdmFunction("MainDB.Store", "HammingDistance")] public static int GetHammingDistance(long hash1, long hash2) { throw new NotSupportedException("This method can only be used in a LINQ-to-Entities query"); } } 

Usage:

 var query = (from p in VisibleObjects.OfType<Photo>() let hd = EdmFunctionMapping.GetHammingDistance(targetPhoto.Analysis.Hash, p.Analysis.Hash) let cd = Math.Abs(targetPhoto.Analysis.High.Red - p.Analysis.High.Red)+ Math.Abs(targetPhoto.Analysis.High.Green - p.Analysis.High.Green)+ Math.Abs(targetPhoto.Analysis.High.Blue - p.Analysis.High.Blue) + Math.Abs(targetPhoto.Analysis.Low.Red - p.Analysis.Low.Red) + Math.Abs(targetPhoto.Analysis.Low.Green - p.Analysis.Low.Green) + Math.Abs(targetPhoto.Analysis.Low.Blue - p.Analysis.Low.Blue) where hd < 5 || (hd < 15 || cd < 100) orderby hd ascending select p).Take(50); return query.ToList(); 

où VisibleObjects n'évalue pas le Enumerable. Ici c'est quand même:

 static IEnumerable<GlobalObject> VisibleObjects { get { return from obj in db.GlobalObjectSet where obj.IsVisible && !obj.SiteUser.IsDeactivated orderby obj.ID descending select obj; } } 

Tout avait l'habitude de fonctionner il y a deux ou trois semaines, et dans cet intervalle j'ai ajouté / enlevé beaucoup de choses et je n'ai pas vérifié si Hamming Distance fonctionnait ou non, donc je ne peux rien dire à propos de quand ça s'est cassé. Cela ne marche plus, c'est comme si l'atsortingbut EdmFunction n'était pas là, essayant d'évaluer dans mon application et rejetant l'exception que j'ai écrite en disant qu'elle ne pouvait être utilisée que dans une requête L2E. J'ai tout vérifié, même recréé complètement la database et généré à partir d'EDMX, et créé et importé la fonction en utilisant Update Model de Database, et il voit la fonction dans EDMX, et il est disponible (évidemment) dans le file EDMX Section SSDL telle que:

  <Function Name="HammingDistance" ReturnType="int" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo"> <Parameter Name="first" Type="bigint" Mode="In" /> <Parameter Name="second" Type="bigint" Mode="In" /> </Function> 

Mais quand il s'agit de l'application, il ne sera pas cartographier à EDM! Essayé plusieurs fois, en créant toute la database à partir de zéro, rien ne change, il jette l'exception dans query.ToList() , et il n'y a pas d'exception interne (cela est logique car il lance ma propre exception, qui ne devrait PAS être exécutée par l'application ). Je n'ai aucune idée de la source du problème, je manque quelque chose d'évident?

Si elle ne reconnaît pas votre fonction mappée Edm, assurez-vous que vous n'avez pas accidentellement changé la requête en linq-to-objects quelque part parce que c'est exactement la raison pour laquelle vous pouvez voir cette erreur. Pour valider cela, essayez simplement de créer une autre requête de test qui ne fera que diriger l'access à l'entité et appeler votre fonction. Quelque chose comme:

 long hash = targetPhoto.Analysis.Hash; var query = from p in db.GlobalObjectSet.OfType<Photo>() select new { EdmFunctionMapping.GetHammingDistance(hash, p.Analysis.Hash) }; 

Si une telle requête passe, vous avez certainement problème mentionné.

Modifier:

Je pense que je vois le problème maintenant. Vos VisibleObjects renvoient IEnumerable => linq-to-objects. Essayez ceci à la place:

 public static IQueryable<GlobalObject> GetVisibleObjects(this IQueryable<GlobalObject> query) { return from obj in query where obj.IsVisible && !obj.SiteUser.IsDeactivated orderby obj.ID descending select obj; } 

Et appelez votre méthode comme:

 from p in db.GlobalObjectSet.GetVisibleObjects().OfType<Photo>() ...