Frage

Ich habe eine skalare Funktion im DB

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

Jetzt möchte ich es in meiner .NET C # oder VB.NET-Code auszuführen.

Ich benutze Entity Framework, versuchte ich es mit Funktionszuordnung zu kartieren und ich habe nicht den Erfolg. i do not care es mit einfachen DbCommand zu tun, das Problem ist, dass ich keine Ergebnisse (die Funktion existiert in der Entities-Klasse) erhalten:

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;
}

Gibt es eine Lösung? Beiträge entweder in C # oder VB.NET wird welcommed werden.

War es hilfreich?

Lösung

Es klingt wie die rechts Art und Weise in diesem Fall ist die Funktionalität des Entity Framework zu verwenden, um eine .NET-Funktion zu definieren, und dass auf Ihren UDF Karte, aber ich glaube, ich sehe, warum Sie don‘ t erhalten das Ergebnis, das Sie erwarten, wenn Sie ADO.NET verwenden, es zu tun - Sie können es doch sagen, Sie eine gespeicherte Prozedur anrufen, aber du bist wirklich eine Funktion aufrufen.

Versuchen Sie folgendes:

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 
    }
}

Andere Tipps

Diese

ist sehr ähnlich zu der obigen Antwort, aber die folgenden Code können Sie eine benutzerdefinierte Funktion mit einer beliebigen Anzahl von Parametern aufrufen und jede Rückgabetyp. Dies könnte als eine allgemeine Lösung nützlich sein. Dies wird auch nicht gründlich getestet worden ... Ich denke, es wird einige Probleme mit Varchars hat.

public class MyDBAccess
{
    private SqlConnection sqlConnection = new SqlConnection("databaseconnectionstring");

    public int GetUserIdByUsername(string username)
    {
        int userID = CallUDF<int>("dbo.fn_GetUserId_Username", new SqlParameter("@Username", username));
        return userID;
    }

    internal static T1 CallUDF<T1>(string strUDFName, params SqlParameter[] aspParameters)
    {
        using (SqlConnection scnConnection = sqlConnection)
        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 SqlDbType TypeToSqlDbType<T1>()
    {
        if (typeof(T1) == typeof(bool))
        {
            return SqlDbType.Bit;
        }
        else if (typeof(T1) == typeof(int))
        {
            return SqlDbType.Int;
        }
        //
        // ... add more types here
        //
        else
        {
            throw new ArgumentException("No mapping from type T1 to a SQL data type defined.");
        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top