C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: Linq の例外の対処法について


(過去ログ 169 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■97655 / inTopicNo.1)  Linq の例外の対処法について
  
□投稿者/ あああ (1回)-(2021/06/23(Wed) 11:31:28)

分類:[C#] 

現在Linqで条件に合ったデータをデータベースから抜き出して、ラベルに表示する処理をおこなっています。
実行すると、一度は欲しい数値が取れているようですが、そのあとに例外が発生してしまいます。
原因や解決策等分かる方いらっしゃいましたらよろしくお願いします。

using (var ctx = new DBContext())
{
// 手動で入力された品番と記号
var hinban = txbHinban.Text;
var kigou = txbKigou.Text;

// 手動入力された品番、記号と同じ品番、記号のデータをDBのMasterテーブルから抜き出し、最終的にその枚数データだけを取り出す処理
Label.Text = ctx.Master.FirstOrDefault(x => x.Hinban == hinban && x.Kishu == kigou).Maisu.ToString(); ←ここで例外が発生
}

例外内容:
 System.NullReferenceException
 オブジェクト参照がオブジェクト インスタンスに設定されていません。
 FirstOrDefault()がnullを返しました。

引用返信 編集キー/
■97656 / inTopicNo.2)  Re[1]: Linq の例外の対処法について
□投稿者/ とっちゃん (727回)-(2021/06/23(Wed) 12:26:59)
No97655 (あああ さん) に返信
> 例外内容:
>  System.NullReferenceException
>  オブジェクト参照がオブジェクト インスタンスに設定されていません。
>  FirstOrDefault()がnullを返しました。
>

FirstOrDefault() は、First()同様条件式 にマッチした「最初のアイテム」を返します。

ですが!

マッチするアイテムが見つからない場合は default インスタンス(class なら null)を返します。


> Label.Text = ctx.Master.FirstOrDefault(x => x.Hinban == hinban && x.Kishu == kigou).Maisu.ToString(); ←ここで例外が発生

とあるので、ctx.Master という集合に、Hinban と Kishu が一致するものが見つからないことが原因です。

この場合は、以下のように見つからない場合を考慮して処理するのが一般的です。

var obj = ctx.Master.FirstOrDefault( x => x.Hinban == hinban && x.Kishu == kigou );
if( obj is not null ){ Label.Text = obj.Maisu.ToString(); }

引用返信 編集キー/
■97657 / inTopicNo.3)  Re[2]: Linq の例外の対処法について
□投稿者/ あああ (3回)-(2021/06/23(Wed) 13:30:42)
No97656 (とっちゃん さん) に返信
> ■No97655 (あああ さん) に返信
>>例外内容:
>> System.NullReferenceException
>> オブジェクト参照がオブジェクト インスタンスに設定されていません。
>> FirstOrDefault()がnullを返しました。
>>
>
> FirstOrDefault() は、First()同様条件式 にマッチした「最初のアイテム」を返します。
>
> ですが!
>
> マッチするアイテムが見つからない場合は default インスタンス(class なら null)を返します。
>
>
>>Label.Text = ctx.Master.FirstOrDefault(x => x.Hinban == hinban && x.Kishu == kigou).Maisu.ToString(); ←ここで例外が発生
>
> とあるので、ctx.Master という集合に、Hinban と Kishu が一致するものが見つからないことが原因です。
>
> この場合は、以下のように見つからない場合を考慮して処理するのが一般的です。
>
> var obj = ctx.Master.FirstOrDefault( x => x.Hinban == hinban && x.Kishu == kigou );
> if( obj is not null ){ Label.Text = obj.Maisu.ToString(); }
>

ご指摘ありがとうございます。参考にしながらコードを見直そうと思います。
しかし、データがNullになる原因としましては、DBにはあらかじめ該当するデータは登録してあるので、DBとの接続がうまくいっていないせいでデータを取ってこれていないのかもしれません…。
うまく接続されているかどうかを確認する方法などはありますでしょうか?
EntityFrameworkを利用しています。
引用返信 編集キー/
■97658 / inTopicNo.4)  Re[3]: Linq の例外の対処法について
□投稿者/ Hongliang (1182回)-(2021/06/23(Wed) 14:03:52)
接続がうまくいっていない場合、FirstOrDefault()でnullが返されるのではなく、例外がスローされますので明確に区別できます。

マッチしない可能性としては、
・hinbanやkisyuといった変数に格納されている値が想定のものではない
・文字列比較の際の大文字小文字の区別
・NULL
などが考えられます。

例えば、以下のようなコードで各行の値と比較結果を表示してみてはいかがでしょう。
foreach (x in ctx.Master.Select(x => new { x.Hinban, x.Kishu, HTest = x.Hinban == hinban, KTest = x.Kishu == kigou })) {
    Trace.WriteLine($"{x.Hinban}, {x.Kishu}, {x.HTest}, {x.KTest}");
}

引用返信 編集キー/
■97659 / inTopicNo.5)  Re[3]: Linq の例外の対処法について
□投稿者/ WebSurfer (2271回)-(2021/06/23(Wed) 14:08:39)
No97657 (あああ さん) に返信

>>var obj = ctx.Master.FirstOrDefault( x => x.Hinban == hinban && x.Kishu == kigou );
>>if( obj is not null ){ Label.Text = obj.Maisu.ToString(); }
>>
>
> ご指摘ありがとうございます。参考にしながらコードを見直そうと思います。
> しかし、データがNullになる原因としましては、DBにはあらかじめ該当するデータは登録してあるので、DBとの接続がうまくいっていないせいでデータを取ってこれていないのかもしれません…。
> うまく接続されているかどうかを確認する方法などはありますでしょうか?

それを聞く前にobj が null になっているかは確認したんですか? まだならやってからその結果の
連絡と共に聞きましょう。

ちなみに、DB との接続の問題(DB サーバーがダウンしているとか、LAN ケーブルが抜けてるとか)
なら NullReferneceException とは別の例外が出るはずです。
引用返信 編集キー/
■97660 / inTopicNo.6)  Re[4]: Linq の例外の対処法について
□投稿者/ あああ (4回)-(2021/06/23(Wed) 14:17:29)
No97658 (Hongliang さん) に返信
> 接続がうまくいっていない場合、FirstOrDefault()でnullが返されるのではなく、例外がスローされますので明確に区別できます。
>
> マッチしない可能性としては、
> ・hinbanやkisyuといった変数に格納されている値が想定のものではない
> ・文字列比較の際の大文字小文字の区別
> ・NULL
> などが考えられます。
>
> 例えば、以下のようなコードで各行の値と比較結果を表示してみてはいかがでしょう。
> foreach (x in ctx.Master.Select(x => new { x.Hinban, x.Kishu, HTest = x.Hinban == hinban, KTest = x.Kishu == kigou })) {
> Trace.WriteLine($"{x.Hinban}, {x.Kishu}, {x.HTest}, {x.KTest}");
> }

そうなんですね。実行すると例外ではなくNullが返ってくるので接続はうまくいっているようです…。
DBのデータは1データしか入っていない状況で、
ctx.Master.Count();
を行うをCountが0で返ってきます。
DBには手入力でデータを入れたのですが、それだとデータとして反映されないなどあるのでしょうか?
引用返信 編集キー/
■97664 / inTopicNo.7)  Re[5]: Linq の例外の対処法について
□投稿者/ 魔界の仮面弁士 (3138回)-(2021/06/23(Wed) 15:02:42)
No97660 (あああ さん) に返信
> DBには手入力でデータを入れたのですが、それだとデータとして反映されないなどあるのでしょうか?

1) 手入力後にコミットし忘れていたため、C# 側からそのデータを読み取れない状態だった。
2) データベースがプロジェクト内の LocalDB などになっていて、実行のたびに古いデータファイルで上書きされている。
3) 接続先のミスで、手入力したデータベースと C# が見ているデータベースが異なるインスタンスだった。
引用返信 編集キー/
■97665 / inTopicNo.8)  Re[6]: Linq の例外の対処法について
□投稿者/ あああ (5回)-(2021/06/23(Wed) 15:12:37)
No97664 (魔界の仮面弁士 さん) に返信
> ■No97660 (あああ さん) に返信
>>DBには手入力でデータを入れたのですが、それだとデータとして反映されないなどあるのでしょうか?
>
> 1) 手入力後にコミットし忘れていたため、C# 側からそのデータを読み取れない状態だった。
> 2) データベースがプロジェクト内の LocalDB などになっていて、実行のたびに古いデータファイルで上書きされている。
> 3) 接続先のミスで、手入力したデータベースと C# が見ているデータベースが異なるインスタンスだった。

接続先のミスで、目的のDBを見れていなかった為でした。
修正したところ無事にデータを取得することができました。ありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -