質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

ASP.NET Web API

ASP.NET Web APIはブラウザやモバイル機器のようなクライアント向けのHTTPサービスを構築するフレームワークです。Microsoft .NET Frameworkがベースになっており、RESTfulサービスを構築するには理想的です。

Q&A

解決済

1回答

1539閲覧

「ASP.NET WebAPI」 PostgresDBで取得したデータを変数に代入する際の疑問点

yt07

総合スコア7

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

ASP.NET Web API

ASP.NET Web APIはブラウザやモバイル機器のようなクライアント向けのHTTPサービスを構築するフレームワークです。Microsoft .NET Frameworkがベースになっており、RESTfulサービスを構築するには理想的です。

0グッド

0クリップ

投稿2021/04/09 11:58

編集2021/04/09 12:59

ASP.NET C#初学者です。
WebAPIを作成するために、ドキュメントに沿って学習しています。DBと連携しパラメータによって動的にデータを返すことを想定し、試しに単純なテストデータから任意のカラムデータを変数に代入する際にスコープの問題か変数への代入後の参照がうまくできず、フィールド変数で定義した場合は参照できましたが以下のコードの場所ではデバッグ実行できません。

開発環境(windows10, VisualStudio2015 Express for web, .NET Framework4.5.2)

テーブルデータは以下になります。

idnameage
1taro19
2tadokoro24
```C#
using AnimalsAppFor_C.Models;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Web.Http;

namespace AnimalsApp.Controllers
{
[RoutePrefix("api/animals")]
public class AnimalsController : ApiController
{
//①フィールド変数で定義すると値が割り当てられる。
string test;

Animal[] products = new Animal[] { //今回は関係がないので省略。 }; [HttpGet] [Route("")] public IEnumerable<Animal> GetAllAnimals() { return products; } [HttpGet] [Route("{id}")] public IHttpActionResult GetAnimal(int id) { //接続文字列 string conn_str = "Server=localhost;Port=5432;User ID=postgres;Database=postgres;Password=パスワード;Enlist=true";

      //②リストクラスを定義したtest_listは正常にretunされる。
List<string> test_list = new List<string>();
//↓③これだと未割当のローカル変数が使用されましたとでる。
//string test;
using (var conn = new NpgsqlConnection(conn_str))
{
//PostgreSQLへ接続
conn.Open();
Debug.WriteLine("Connection success!");

var command = new NpgsqlCommand(@"select * from person", conn);
//↓④これだと現在のコンテキストに'test'は存在しませんとでる。
//string test;
var dataReader = command.ExecuteReader();
int i = 0;
while (dataReader.Read())
{
Debug.WriteLine("value : {0},", dataReader["name"]);
//配列ver
test_list.Add((string)dataReader["name"]);
//文字列ver
test = (string)dataReader["name"];
Debug.WriteLine(i + ":" +test);
i = i + 1;
}
conn.Close();
}

return Ok(test); /* ①の結果:"tadokoro" ③の結果:未割当のローカル変数が使用されましたとでる。デバック実行不可。

        ④の結果:現在のコンテキストに'test'は存在しませんとでる。デバック実行不可。
*/
//return Ok(test_list ); >> ②結果:["taro","tadokoro"]
}
}
}

④の場合、スコープによる参照ができていない問題だと思うのですが、③の場合、②と同じ場所に定義していますが、②は参照され、③は未割り当てとなるのはなぜでしょうか? そもそもwhile内に文字列として入れていることが不格好ですが、なぜ③のケースはダメなのか調べましたが思うような結果を得られず質問させていただきました。 何か参考になるサイトまたはご教授いただけないでしょうか? お願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/04/09 12:39

開発環境(OS, Visual Studio, .NET Framework のバージョンなど)を書いてください。 ASP.NET のタグもつけてください。自分の都合で恐縮ですが ASP.NET Web API は見てないので。
yt07

2021/04/09 13:01

失礼いたしました。 環境環境、タグ付け追記しました。
退会済みユーザー

退会済みユーザー

2021/04/09 13:29

ASP.NET Web API の質問ではなくて、ADO.NET + Npgsql を使った .NET Framework の C# アプリからの PostgreSQL への接続、SELECT クエリの実行、データの取得の問題のように見えます。ASP.NET Web API 関係なく、そこだけわかればいいのでしょうか?
yt07

2021/04/09 13:48

切り分けができておらず申し訳ございません。 今回は言っていただいたように、データ取得後のデータを変数に格納し、APIをたたいた結果を表示するにあたり、変数の定義の疑問について質問させていただきましたので、その部分だけわかれば大丈夫です。
guest

回答1

0

ベストアンサー

表題に、

「ASP.NET WebAPI」 PostgresDBで取得したデータを変数に代入する際の疑問点

と書いてありましたが、「ASP.NET Web API」も「PostgresDB で取得」もこのスレッドの課題とは直接関係なくて、変数を宣言する場所、初期化(割り当て)、スコープの話で、string test; を宣言する場所を、

① クラスのフィールドとして宣言、または

③ メソッド内のローカル変数として宣言、または

④ メソッド内の using { } 内のローカル変数として宣言

と変えると、結果が変わるのは何故かという話ですよね。

④の場合、スコープによる参照ができていない問題だと思うのですが、

その通りです。using { } 内で宣言しているので、その { } 外では「現在のコンテキストに'test'は存在しません」となります。

③の場合、②と同じ場所に定義していますが、②は参照され、③は未割り当てとなるのはなぜでしょうか?

② は List<string> test_list = new List<string>(); となっており、変数 test_list 宣言だけでなく、new List<string>() によって List<string> 型のインスタンスが生成され、それへの参照が変数 test_list に代入されています。

一方、③ は string test; となっており、変数 test が宣言されているのみで、そこでは test が指す実体(インスタンス)がありません。while 文の中で代入されるようコーディングされていますが、コンパイラには実行時に while の条件が true になって (string)dataReader["name"] が代入されるかわ分からないのでエラーにしています。

③ のところで string test = null; としておけばエラーにはならないはずです。

そのあたりはエラーメッセージ「未割当のローカル変数が使用されました」ググるといろいろヒットするのでやってみてください。

なお、① の場合は string test; のままで自動的に null が使用されるようです。

イメージ説明

投稿2021/04/10 01:19

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yt07

2021/04/10 04:37

ありがとうございます。 疑問が解決しスッキリしました。 ③string test = null;と既定値を割り当てることでエラーにならず思っているデータが表示されました。 調べてみるとstring test = default(string);としてもエラーなく同様に表示されました。 基礎的なところが理解できていませんでした。 ありがとうございます。
退会済みユーザー

退会済みユーザー

2021/04/10 22:46 編集

default(string) は null です。 もし、null は使いたくないということがあれば、"" とか "仮" でもいいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問