2017-02-20 42 views
2

我想返回一個基於隱式表類型的自定義(複合)類型。如何從Npgsql和存儲過程返回自定義表類型?

我有這樣的表定義:

CREATE TABLE app_user (id CHAR(36) PRIMARY KEY, name TEXT); 

被映射到這個類的定義:

public class ApplicationUser 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
} 

這是通過調用映射:

NpgsqlConnection.MapCompositeGlobally<ApplicationUser>("app_user"); 

我試圖使用此存儲過程返回記錄:

CREATE FUNCTION find_by_id(user_id app_user.id%TYPE) RETURNS app_user AS $$ 
DECLARE 
    found_user app_user; 
BEGIN 
    SELECT * 
    FROM app_user 
    WHERE id = user_id 
    INTO found_user; 

    RETURN found_user; 
END 
$$ LANGUAGE plpgsql STABLE SECURITY DEFINER; 

我敢從C#調用是這樣的:

ApplicationUser user; 
using (NpgsqlConnection db = new NpgsqlConnection(this.connectionString)) 
{ 
    db.Open(); 
    using (NpgsqlCommand cmd = new NpgsqlCommand("find_by_id", db)) 
    { 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.Parameters.AddWithValue("user_id", userId); 
     object result = cmd.ExecuteScalar(); 
     user = result == DBNull.Value ? null : (ApplicationUser)result; 
    } 
} 

但鑄造resultApplicationUser當我得到一個異常:

InvalidCastException: Unable to cast object of type 'System.String' to type 'MyApp.ApplicationUser'. 

這顯然是因爲result只是字符串Id ,但爲什麼我的複合app_user對象不是result

我也嘗試用out參數返回對象,但遇到了完全相同的異常。我試圖用Npgsql做什麼,或者我必須在C#中從各個列中手動重新構建對象ApplicationUser

我正在使用Npgsql v3.2.0和PostgreSQL v9.6。

回答

1

看起來像我想出來的。結果比我想象的要容易。我需要改變的是存儲過程從C#調用的方式。

ApplicationUser user; 
using (NpgsqlConnection db = new NpgsqlConnection(this.connectionString)) 
{ 
    db.Open(); 
    using (NpgsqlCommand cmd = new NpgsqlCommand("SELECT find_by_id(@user_id);", db)) 
    { 
     cmd.Parameters.AddWithValue("user_id", userId); 
     object result = cmd.ExecuteScalar(); 
     user = result == DBNull.Value ? null : (ApplicationUser)result; 
    } 
} 

我更喜歡調用存儲過程的其他方式,但至少這個作品!

相關問題