Entity Framework Core SQLQuery

Ich bin ein mittelmäßiger EF Nutzer. Sobald es mir zu komplex wird, bau ich mir die TSQL Kommandos selber und schicke die über den EF Layer.

So habe ich das mit .NET Framework Entity Framework gefühlt ewig gemacht. Raw SQL Query und ein Poco Klasse samt SQL Parameter. Fertig war eine einzeilige Suchimplementierung.

db.Database.SqlQuery<ADR_ManagedBI>(sql, new SqlParameter("@suche", Suche));

Nun wollte ich den klassik .NET Code nach .NET core 6 (so heißt es eigentlich gar nicht) migrieren.

Die einfachste Lösung die ich gefunden habe, um das Verhalten von SQLQuery in core nachzubauen ist per FromSqlInterpolated. Dazu muss allerdings die Poco Klasse der DBContext Klasse als DbSet hinzugefügt werden.

   1:  public virtual DbSet<AdrManagedBI> AdrManagedBI { get; set; } = null!;

Das ist bisher nicht nötig, ebenso wenig wie das Attribut Keyless auf der Entitätsklasse. Dieses müssen sie in der C# Poco Datei einfügen. Das ist ein relativ neues Feature, bisher musste man das per Fluent Api in OnModelCreating erledigen (kein Fan der Fluent Api).

Wenn Sie schon mal in der Klasse den Code ändern, dann auch alle Felder, die Null Rückgaben aus dem SQL Befehl erhalten könnten- Nullable mit ?. Im klassischen Entity Framework wurden dort automatisch Leer Werte oder 0 eingefügt. Core wirft ne fiese Exception

System.Data.SqlTypes.SqlNullValueException: "Data is Null. This method or property cannot be called on Null values."

Nun geht es an den SQL String. Auch hier sind die Unterschiede erheblich. Laut der spärlichen Dokumentation kann man noch SQL Parameter verwenden. Allerdings sind nun auch String Interpolation Parameter ({0} oder {name}) möglich, die intern dann wieder in die sicheren SQLParameter übersetzt werden. Stichwort SQL Injection.

Dafür braucht es allerdings eines neuen Datentyp, der SQL Zeichenkette und Parameterliste enthält. Mit FormattableString statt string. Das @ Zeichen benötigt man für mehrzeilige Strings in C# ohne extra “”. Das $ Zeichen für die String Interpolation.

   1:    FormattableString sql = $@"  SELECT        ADR_ManagedID, GroupName, Bearbeiter, I...
   2:  WHERE        (dbo.ADR_Managed.GroupName LIKE '%'+{Suche}+'%')
   3:                          ...";

Um eine Wildcard Suche eines Substrings in TSQL zu realisieren, musste man schon immer eine etwas schräge Syntax mit % Zeichen einsetzen. Die werden dann als String Operation addiert, auch in C#.

Das sah vorher so aus:

WHERE        (dbo.ADR_Managed.GroupName LIKE '%'+@suche+'%')

Zu guter Letzt wird das SQL Kommando noch wie vormals mit SQLQuery nun mit FromSQLInterpolated (auch FromSQLRaw) sicher mit Parameter abgeschickt.

 

   1:   var result = db.AdrManagedBI.FromSqlInterpolated<AdrManagedBI>(sql);
   2:   ListManaged = result.AsNoTracking().ToList();

Alternativ auch ausprobiert und erfolgreich getestet

db.Set<AdrManagedBI>().FromSqlInterpolated<AdrManagedBI>(sql);

Ich hatte gehofft, das es dann nicht nötig ist, dem DBContext hinzuzufügen. Ist aber nicht so. Microsoft will wohl über x EF-Optionen uns das Leben noch ein Stück härter machen.

Kommentare sind geschlossen