2009-06-29 50 views
7

我在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 

現在,我想我的.NET C#或VB.NET代碼中運行它創建了一個標量函數。

我使用實體框架,我試圖映射它與功能映射,我沒有成功。 我不在乎用簡單的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 2009-06-29 03:13:31

+3

@Shimmy:指定所有者的名稱,「dbo」 - >「select dbo.fn_GetUserId_Username(@Username)」 – Sung 2009-06-29 03:20:23

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."); 
    } 
} 
相關問題