web-dev-qa-db-fra.com

Appel de fonctions définies par l'utilisateur dans Entity Framework 4

J'ai une fonction définie par l'utilisateur dans une base de données SQL Server 2005 qui renvoie un peu. Je voudrais appeler cette fonction via Entity Framework. J'ai cherché et n'ai pas eu beaucoup de chance.

Dans LINQ to SQL, c'était incroyablement facile, j'ajouterais simplement la fonction au modèle de contexte de données, et je pourrais l'appeler comme ça.

bool result = FooContext.UserDefinedFunction(someParameter);

En utilisant l'Entity Framework, j'ai ajouté la fonction à mon modèle et elle apparaît sous SomeModel.Store\Stored Procedures dans le navigateur de modèle.

Le modèle n'a généré aucun code pour la fonction, le XML du fichier .edmx contient:

<Function Name="UserDefinedFunction" ReturnType="bit" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
    <Parameter Name="someParameter" Type="int" Mode="In" />
</Function>

Le plus proche que j'ai pu obtenir était quelque chose comme ceci:

bool result = ObjectContext.ExecuteFunction<bool>(
    "UserDefinedFunction",
    new ObjectParameter("someParameter", someParameter)
).First();

Mais j'ai reçu le message d'erreur suivant:

FunctionImport 'UserDefinedFunction' est introuvable dans le conteneur 'FooEntities'.

Les noms ont été changés pour protéger les innocents.

tldr: Comment appeler des fonctions définies par l'utilisateur à valeur scalaire en utilisant Entity Framework 4.0?

21
Evil Pigeon

Je l'ai finalement résolu: D Pour les fonctions scalaires, vous pouvez ajouter la clause FROM {1}.

bool result = FooContext.CreateQuery<bool>(
    "SELECT VALUE FooModel.Store.UserDefinedFunction(@someParameter) FROM {1}",
    new ObjectParameter("someParameter", someParameter)
).First();

C'est certainement un cas pour utiliser LINQ to SQL sur EF.

23
Evil Pigeon

appel de la fonction SQL de type statique définie par l'utilisateur

Vous pouvez utiliser ExecuteStoreQuery,

  • le premier paramètre prend l'instruction d'appel de la fonction SQL au format chaîne
  • le second paramètre prend un objet de la classe SqlParameter dans lequel vous passez le nom de votre paramètre de fonction avec sa valeur. comme indiqué dans la méthode ci-dessous
public  string GetNumberOFWorkDays(Guid leaveID)
{
  using (var ctx  = new INTERNAL_IntranetDemoEntities())
  {
    return ctx.ExecuteStoreQuery<string>(
                  "SELECT [dbo].[fnCalculateNumberOFWorkDays](@leaveID)",
                  new SqlParameter { ParameterName = "leaveID", Value = leaveID }
               ).FirstOrDefault();
   }
}
7
Sachin Verma

Si vous souhaitez appeler une fonction table dans MS SQL via Entity Framework; Vous pouvez utiliser ceci:

var retval = db.Database.SqlQuery<MyClass>(String.Format(@"select * from dbo.myDatabaseFunction({0})", id));
6
Oguzhan KIRCALI

Appel d'une fonction dans EF4 avec ODPNET beta 2 (Oracle), qui renvoie un NUMBER:

using (var db = new FooContext())
{
    var queryText = "SELECT FooModel.Store.MY_FUNC(@param) FROM {1}"
    var result = db.CreateQuery<DbDataRecord>(queryText,new ObjectParameter("param", paramvalue));
    return result.First().GetDecimal(0);
}

Je l'ajoute ici parce que sur la base du code d'Evil Pigeon, je pourrais le comprendre pour Oracle. (Également voté sa réponse).

4
Hoagie

ObjectResult result = context.ExecuteStoreQuery ("select EmployeeName from User where Id = {0}", 15);

http://msdn.Microsoft.com/en-us/library/ee358758.aspx

3
DipakRiswadkar

Vous pourriez trouver this utile. Il semblerait que vous ne pouvez les appeler que via eSQL directement et sans utiliser Linq.

1
Ben Robinson

pensé id ajouter une note pour toute autre personne qui rencontre cela, si votre paramètre de fonction sql est nullable, vous devez appeler la fonction dans sql avec la valeur du paramètre "default". Pour appeler une fonction comme celle-ci en utilisant Entity Framwork, essayez

bool result = FooContext.CreateQuery<bool>(
"SELECT VALUE FooModel.Store.UserDefinedFunction(null) FROM {1}"
).First();
0
Andy Mo