كيفية استخدام وظائف المعرفة من قبل المستخدم SQL في. NET؟

StackOverflow https://stackoverflow.com/questions/1056390

سؤال

وأنا خلق وظيفة العددية في 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

والآن أريد أن تشغيله داخل بلدي. 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;
}

هل هناك حل؟ سيتم welcommed المشاركات في إما C # أو VB.NET.

هل كانت مفيدة؟

المحلول

وهذا يبدو وكأنه الطريق <م> الحق في هذه الحالة هو استخدام وظيفة إطار كيان لتعريف دالة. 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 
    }
}

نصائح أخرى

وهذه هي تشبه الى حد بعيد الجواب أعلاه، ولكن رمز أدناه يسمح لك لاستدعاء UDF مع أي عدد من المعلمات وأي نوع الإرجاع. قد يكون هذا مفيدا كحل أعم. هذا لم يتم اختباره أيضا بدقة ... وأعتقد أنه سيكون لها بعض المشاكل مع varchars.

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.");
        }
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top