Presmerovaním a prípadne null odkaz Jednotka v Rámci 6 dotaz

0

Otázka

Mám .ČISTÝ 6 projekt s nullable referenčné typy enabled (<Nullable>enable</Nullable>). Mám tento EF jednotka:

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; }
}

Pridal som ? vyššie zabrániť tejto nullable upozornenie:

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

Teraz, mám tento Entity Framework 6 LINQ dotazu:

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

... ale ja si nasledujúce upozornenie:

Dereference of a possibly null reference.

... na tejto časti môjho dotazu:

x.User.Id == ...

Ako to môžem opraviť varovanie?

4

Najlepšiu odpoveď

2

Myslím, že máte na mysli niečo ako:

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é vydanie je varovanie, že C#8 predstavil s tým, že viac explicitné s null-možnosť referenčné typy. Pre účtovná jednotka, nad implementácia nie je platné, pokiaľ nie sú tieto vzťahy sú síce nepovinné, ktoré by si vyžadovali ich FK polia (UserId a PostId), aby aj Null-schopný. Oni pravdepodobne sú nie voliteľné.

Hlavné možnosti na riešenie tohto:

A) vypnúť funkciu. (Zakázať null-možnosť odkazy v projekte)

B) Žiadať "odpustenie" za to, že tieto by mali byť nikdy null, ale nebude v platnom štátu na výstavbu. (EF bude ich spravovať)

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!;
}

Zmena modelu označiť navigáciu vlastnosti ako null-možnosť odkazy je spôsobilá zapríčiniť, všetky druhy problémov, ako s migrácie môže, a začne výmena non-null-možnosť FKs s null-vedieť ty. Označiť tieto odkazy, tak Null-schopný a udržať EF happy:

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; }
}

Čo je takmer určite nie je to, čo chcete vo vašej doméne, alebo aj právne ak UserId a PostId sú súčasťou PK.

Osobne som sa chalking táto zmena v C# ako "mínu" MS povolené pôvodne štandardne, ako na Strane Klienta Hodnotenie v EF. :) Som predvídať veľa-a-StackOverflow otázky okolo tohto varovania alebo lámanie zmeny, a veľa-a-klient codebases podstielky s "!" odpustenie značky ako starší než null-možnosť objekty/odkazy sú prešiel do kódu s null-možnosť kontroly referencií.

2021-11-24 23:15:24
1

Mali by ste označiť navigáciu osoby ako nullable. Nemali by ste mať lazy loading povolené, a preto navigáciu vlastnosti môžu byť vrátené ako null z dotazov. Dokonca, ak sú požadované v databáze, váš kód nemá ich načítať.

V dopytu, vyjadrenia, môžete si byť istí, že Subjekt, Rámec nebude vykonávať ich clientside, ale analyzovať SQL dotaz z nich.

Preto:

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

Môžete povedať, kompilátor s User! že viete, že to nebude mať hodnotu null tam. Ak zapnete clientside hodnotenie, ale nemali by ste sa a ak tak urobíte, budete potrebovať null skontrolujte tam tak či tak.

Ako na použitie PostFile.User, ako napríklad:

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

Tam môže byť null ak ste nezadali Include(p => p.User) a nemusíte lazy loading povolené, tak user bude potrebovať null kontrola pred prevádzkou.

Ak budete robiť použiť lazy loading, môžete vypnúť upozornenie:

#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 si, že je potrebné tento:

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

A zavolať

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

Č. Nie označenie tieto vlastnosti, ako nullable robí kompilátor vydávať varovania, ktoré nemusia byť inicializovaný, čo je pravda.
CodeCaster
0

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

2021-11-24 22:53:01

V iných jazykoch

Táto stránka je v iných jazykoch

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