2009-06-29 13 views
7

私は今、私は私の.NET C#またはVB.NETのコード内でそれを実行したいDB.NETでSQLユーザー定義関数を使用する方法は?

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER FUNCTION [dbo].[fn_GetUserId_Username] 
    (
    @Username varchar(32) 
    ) 
RETURNS int 
AS 
    BEGIN 
    DECLARE @UserId int 
    SELECT @UserId = UserId FROM [User] WHERE Username = @Username 
    RETURN @UserId 
    END 

でスカラー関数を作成しました。

私はEntity Frameworkを使用していますが、これを関数マッピングでマップしようとしましたが、成功しませんでした。 は、私はシンプルされたDbCommandでそれを行うには気にしない、問題は、私は何の結果(関数は、エンティティクラスに存在する)を取得しないことです:

public int GetUserIdByUsername(string username) 
{ 
    EntityConnection connection = (EntityConnection)Connection;    
    DbCommand com = connection.StoreConnection.CreateCommand(); 
    com.CommandText = "fn_GetUserId_Username"; 
    com.CommandType = CommandType.StoredProcedure; 
    com.Parameters.Add(new SqlParameter("Username", username)); 
    if (com.Connection.State == ConnectionState.Closed) com.Connection.Open(); 
    try 
    { 
     var result = com.ExecuteScalar(); //always null 
    } 
    catch (Exception e) 
    { 
    } 
    return result; 
} 

を任意の解決策はありますか? C#またはVB.NETの投稿は歓迎されます。

答えて

15

右のように聞こえるこの場合、エンティティフレームワークの機能を使用して.NET関数を定義し、それをUDFにマップする方法ですが、結果が得られない理由がわかりますADO.NETを使用してそれを実行するときには期待しています。ストアドプロシージャを呼び出すと言っていますが、実際には関数を呼び出しています。

はこれを試してみてください:

public int GetUserIdByUsername(string username) 
{ 
    EntityConnection connection = (EntityConnection)Connection;    
    DbCommand com = connection.StoreConnection.CreateCommand(); 
    com.CommandText = "select dbo.fn_GetUserId_Username(@Username)"; 
    com.CommandType = CommandType.Text; 
    com.Parameters.Add(new SqlParameter("@Username", username)); 
    if (com.Connection.State == ConnectionState.Closed) com.Connection.Open(); 
    try 
    { 
     var result = com.ExecuteScalar(); // should properly get your value 
     return (int)result; 
    } 
    catch (Exception e) 
    { 
     // either put some exception-handling code here or remove the catch 
     // block and let the exception bubble out 
    } 
} 
+0

結果: SqlExceptionが: 'fn_GetUserId_Usernameは' が認識関数名ではありません。 – Shimmy

+3

@Shimmy:所有者名 "dbo"を指定 - > "dbo.fn_GetUserId_Username(@ユーザー名)を選択" – Sung

+0

それは、ありがとう! – Shimmy

3

これは、上記の答えに非常に似ていますが、以下のコードでは、あなたは、任意の数のパラメータと任意の戻り値の型でUDFを呼び出すことができます。これはより一般的な解決策として有用かもしれません。これは徹底的にテストされていません...私はそれがvarcharsにいくつかの問題があると思います。

internal static T1 CallUDF<T1>(string strUDFName, params SqlParameter[] aspParameters) 
{ 
    using (SqlConnection scnConnection = GetConnection()) 
    using (SqlCommand scmdCommand = new SqlCommand(strUDFName, scnConnection)) 
    { 
     scmdCommand.CommandType = CommandType.StoredProcedure; 

     scmdCommand.Parameters.Add("@ReturnValue", TypeToSqlDbType<T1>()).Direction = ParameterDirection.ReturnValue; 
     scmdCommand.Parameters.AddRange(aspParameters); 

     scmdCommand.ExecuteScalar(); 

     return (T1) scmdCommand.Parameters["@ReturnValue"].Value; 
    } 
} 

private static SqlDbType TypeToSqlDbType<T1>() 
{ 
    if (typeof(T1) == typeof(bool)) 
    { 
     return SqlDbType.Bit; 
    } 
     . 
     . 
     . 
    else 
    { 
     throw new ArgumentException("No mapping from type T1 to a SQL data type defined."); 
    } 
} 
+0

適切かつ華麗です! Thnx。 –

関連する問題