5
Help us understand the problem. What are the problem?

posted at

updated at

C# null許容参照型を有効にした場合のEF Core DbSet<T>の書き方

はじめに

C# 8 から導入されたnull参照許容型ですが、VS2022で新しいプロジェクトを作成するとデフォルトで有効になるようです(私の環境では)。
そこで、既存プロジェクトを参考にEntityFrameworkCoreのDbContextを作っていたところ、少々引っかかったところがあったので備忘録として残しておきます。

現象

いつものようにDbContextDbSet<T>を記載していたのですが……

public class MyDbContext : DbContext
{
    public DbSet<User> Users {get; set;}
}

ここで Usersには破線が表示され、以下の警告が表示されます。

CS8618 null 非許容のフィールドには、コンストラクターの終了時に null 以外の値が入っていなければなりません。Null 許容として宣言することをご検討ください。

とは言っても、ここに値をセットするのは自分じゃあないし……。と思いつつ、当初は以下のようにnull許容して対応していました。

public DbSet<User>? Users {get; set;}

でもこれでは参照する側でnullを考慮した記述をしなきゃならず、ちょっとモヤる感じに。

解決

公式にちゃんと書いてありました

Null 許容参照型の使用 - DbContext と DbSet

以下のように記載しましょう、とのことです。

public class MyDbContext : DbContext
{
    public DbSet<User> Users => Set<User>();
}

これでちゃんと警告なく動くようになりました。以上、万々歳。

追記:Null 免除演算子を使用する方法

コメントより、以下の方法でも可能との指摘を受けました。

public class MyDbContext : DbContext
{
    public DbSet<User> Users  {get; set;} = Null!;
    // または
    // public DbSet<User> Users  {get; set;} = default!;
}

テーブルからリバースエンジニアリングでコードを生成した場合はこちらが使用されるようです。
この方法は自分もBlazorでは以下のように使用したので、この方法もありですね。

    // ExampleRazor.razor.cs
    public partial class ExampleRazor
    {
        [Inject]
        HogeService HogeService { get; set; } = default!;
    }
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
5
Help us understand the problem. What are the problem?