Appel de la fonction scalaire à partir de c # avec Entity Framework 4.0 / .edmx

Je voudrais mapper ma fonction scalaire à mon .edmx mais cela échoue. Je clique avec le bouton droit sur le mappage de mon cadre d’entité et choisis le modèle de mise à jour de la firebase database. Il apparaît dans mon dossier de procédures stockées dans le navigateur de modèle.

Toutefois, lorsque je souhaite l’append à mon dossier Function Imports dans le navigateur de modèle, le message fonction scalaire n’apparaît pas dans la liste déroulante. Est-ce que quelqu’un peut m’aider?

Je peux appeler la fonction scalaire en utilisant l’ancienne méthode, telle que:

 dbContext.ExecuteStoreQuery( "SELECT dbo.getMinActualLoadDate ({0}, {1}, {2}) AS MyResult", LoadPkid, LoadFkStartLoc, TripSheetPkid).First(); 

mais ce n’est pas la meilleure façon. Mon responsable souhaite que je trouve un moyen de placer la fonction scalaire dans le dossier “import de fonction” afin que je puisse appeler la fonction scalaire à l’aide du code suivant au lieu du code précédent:

 dbContext.ExecuteFunction("getMinActualLoadDate ", paramList); 

J’ai essayé d’append une image pour montrer ce que je veux dire, mais comme ma réputation est encore basse, je suis incapable de le faire. Cependant, l’image peut être trouvée ici: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/756865e5-ff25-4f5f-aad8-fed9d741c05d

Merci.

J’ai rencontré le même problème. Et voici la solution que je trouve assez autonome (testé dans EF5, mais devrait également fonctionner dans EF4):

La mise en correspondance immédiate des fonctions de valeur scalaire n’est pas prise en charge, mais vous pouvez les exécuter directement.

Vous pouvez également éditer le fichier edmx pour que edmx génère la méthode appropriée pour la fonction de valeur scalaire, mais elle sera supprimée si vous synchronisez votre modèle avec la firebase database.

Écrivez vous-même l’implémentation d’une fonction à valeur scalaire:

 ssortingng sqlQuery = "SELECT [dbo].[CountMeals] ({0})"; Object[] parameters = { 1 }; int activityCount = db.Database.SqlQuery(sqlQuery, parameters).FirstOrDefault(); 

Ou éditez edmx et ajoutez XML pour une cartographie personnalisée de la fonction scalaire:

   SELECT [dbo].[CountActivities] (@personId)    

Cette information a été trouvée dans ce blog

Voici ma solution à ce problème, qui correspond presque exactement à ce que demandait votre responsable. Cependant, avec 18 mois de retard.

En méthode vanille:

  ///  /// Calls a given Sql function and returns a singular value ///  /// Current DbContext instance /// CLR Type /// Sql function /// Sql function parameters /// Owning schema /// Value of T public T SqlScalarResult(DbContext db, ssortingng sql, SqlParameter[] parameters, ssortingng schema = "dbo") { if (ssortingng.IsNullOrEmpty(sql)) { throw new ArgumentException("function"); } if (parameters == null || parameters.Length == 0) { throw new ArgumentException("parameters"); } if (ssortingng.IsNullOrEmpty(schema)) { throw new ArgumentException("schema"); } ssortingng cmdText = $@"SELECT {schema}.{sql}({ssortingng.Join(",", parameters.Select(p => "@" + p.ParameterName).ToList())});"; // ReSharper disable once CoVariantArrayConversion return db.Database.SqlQuery(cmdText, parameters).FirstOrDefault(); } } 

Et comme méthode d’extension à EF:

 namespace System.Data.Entity { public static class DatabaseExtensions { ///  /// Calls a given Sql function and returns a singular value ///  /// Current DbContext instance /// CLR Type /// Sql function /// Sql function parameters /// Owning schema /// Value of T public static T SqlScalarResult(this Database db, ssortingng sql, SqlParameter[] parameters, ssortingng schema = "dbo") { if (ssortingng.IsNullOrEmpty(sql)) { throw new ArgumentException("sql"); } if (parameters == null || parameters.Length == 0) { throw new ArgumentException("parameters"); } if (ssortingng.IsNullOrEmpty(schema)) { throw new ArgumentException("schema"); } ssortingng cmdText = $@"SELECT {schema}.{sql}({ssortingng.Join(",", parameters.Select(p => "@" + p.ParameterName).ToList())});"; // ReSharper disable once CoVariantArrayConversion return db.SqlQuery(cmdText, parameters).FirstOrDefault(); } } } 

Bien qu’il ne fume pas ici, je suggérerais les tests unitaires avant toute utilisation sérieuse.

Je suppose que vous manquez la boîte de dialog Edit Function Import , dans laquelle vous pouvez générer des types complexes . essayez d’explorer.

entrez la description de l'image ici

Si vous avez créé avec succès les scalars , vous pouvez maintenant naviguer comme ceci

 using (var con = new DatabaseEntities()) { long? invoiceNo = con.sp_GetInvoiceMaxNumber(code.Length + 2).First(); .... } 

La seule solution consiste à convertir le type scalaire de la fonction en type valeur de table avec une valeur unique dans la table. Veuillez consulter l’exemple de code.

Vous n’avez rien à changer dans le fichier XML EDMX, veuillez modifier la fonction SQL.

Fonction scalaire telle qu’elle était, ce qui ne fonctionne pas

 CREATE FUNCTION [dbo].[GetSha256] ( -- Add the parameters for the function here @str nvarchar(max) ) RETURNS VARBINARY(32) AS BEGIN RETURN ( SELECT * FROM HASHBYTES('SHA2_256', @str) AS HASH256 ); END -- this doesn't work. 

Fonction scalaire -> Fonction convertie en table valuée, cela fonctionne

 CREATE FUNCTION [dbo].[GetSha2561] ( -- Add the parameters for the function here @str nvarchar(max) ) RETURNS @returnList TABLE (CODE varbinary(32)) AS BEGIN INSERT INTO @returnList SELECT HASHBYTES('SHA2_256', @str); RETURN; -- This one works like a charm. END 

Capture d’écran Edmx

entrez la description de l'image ici