Dereference snad null odkaz v Entity Framework 6 dotaz

0

Otázka

Mám .NET 6 projektů s možnou hodnotou null referenční typy povoleno (<Nullable>enable</Nullable>). Mám EF subjekt:

public class PostFile {
  public Int32 UserId { get; set; }
  public Int32 PostId { get; set; }

  public virtual User? User { get; set; }
  public virtual Post? Post { get; set; }
}

Přidal jsem ? výše, aby se zabránilo to s možnou hodnotou null upozornění:

Non-nullable property '...' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Teď jsem to Entity Framework 6 LINQ dotazu:

var postFiles = context.postFiles.Where(x => x.User.Id == request.UserId);

... ale já si následující upozornění:

Dereference of a possibly null reference.

... na tuto část mého dotazu:

x.User.Id == ...

Jak mohu opravit toto varování?

4

Nejlepší odpověď

2

Myslím si, že říct něco jako:

public class PostFile {
    public Int32 UserId{ get; set; }
    public Int32 PostId { get; set; }

    public virtual User? User { get; set; }
    public virtual Post? Post { get; set; }
}

Vaše původní otázka je varování, že C#8 představil s tím, že více explicitní s null-možné referenční typy. Pro účetní jednotky, výše plnění není platná, dokud tyto vztahy jsou sice nepovinné, které by vyžadovaly jejich FK polí (Uživatelské jméno a PostId) být také Null-možné. Oni jsou pravděpodobně není volitelné.

Hlavní možností, jak řešit tento:

A) vypněte funkci. (Zakázat null-možné odkazy v projektu)

B) Zeptejte se "odpuštění" za skutečnost, že tyto by nikdy neměla být null, ale není v platném stavu na stavbě. (EF bude spravovat)

public class PostFile {
    public Int32 UserId{ get; set; }
    public Int32 PostId { get; set; }

    public virtual User User { get; set; } = null!;
    public virtual Post Post { get; set; } = null!;
}

Změna modelu označit navigační vlastnosti jako null-možné odkazy, je pravděpodobné, že způsobí, že všechny druhy problémů, jako s migrací to může, a začne nahrazení non-null-možné FKs s null-možné ty. Označit tyto odkazy jako Null-možné a udržet EF šťastný:

public class PostFile {
    public Int32? UserId{ get; set; }
    public Int32? PostId { get; set; }

    public virtual User? User { get; set; }
    public virtual Post? Post { get; set; }
}

Což je téměř jistě není to, co chcete ve vaší doméně, nebo dokonce legální, pokud UserId a PostId jsou součástí PK.

Osobně jsem křídování tato změna v C# jako "pozemní mina" MS zpočátku povoleno ve výchozím nastavení, jako je na Straně Klienta Hodnocení v EF. :) Předvídám, že mnoho-a-StackOverflow otázky kolem tohoto varování nebo lámání změny, a mnoho-to-client codebases plná "!" odpuštění značky jako starší non-null-možné objekty/odkazy jsou předány do kódu s null-možné referenční kontroly.

2021-11-24 23:15:24
1

Měli byste označit navigační subjekty jako s možnou hodnotou null. Neměl jsi líný zatížení povoleno, a proto navigační vlastnosti mohou být vráceny jako null z dotazů. I když jsou potřebné v databázi, váš kód nebude muset načíst.

V dotazu výrazy, můžete si být jisti, že Entity Framework nebude spouštět je clientside, ale analyzovat dotaz SQL z nich.

Proto:

.Where(x => x.User!.Id == request.UserId)

Můžete říct, kompilátor s User! to víš, že to nemá být null. Pokud povolíte clientside hodnocení, ale neměli byste, a pokud tak učiníte, budete potřebovat null podívejte se tam tak jako tak.

Jako pro použití PostFile.Userstejně jako v:

var postFile = dbContext.PostFiles.FirstOrDefault(p => p....) ?? throw ...;
var user = postFile.User;

Tam to může být null pokud jste neměli Include(p => p.User) a nemám lazy loading povoleno, takže user bude potřebovat null přezkoušení před použitím.

Pokud se vám to udělat pomocí lazy loading, můžete zakázat upozornění:

#pragma warning disable CS8618 // EF initializes these properties through lazy loading
    public virtual User User { get; set; }
#pragma warning restore CS8618 
2021-11-24 22:37:30
0

Myslím, že potřebuješ toto:

public class PostFile {
    public User User { get; set; }
    public Post Post { get; set; }
}

A volání

var postFiles = context.postFiles.Where(x => x.User.Id == request.UserId).Include(x => x.Post);
2021-11-24 22:52:47

Ne. Není označení těchto vlastností jako možnou hodnotou null dělá kompilátor vydávat varování, že nemusí být inicializována, což je pravda.
CodeCaster
0

Co var postFiles = context.postFiles.Where(x => x.User != null && x.User.Id == request.UserId);?

2021-11-24 22:53:01

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................