2009-06-29 76 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."); 
    } 
} 
相关问题