Wie zum speichern von JSON in eine Entität Feld mit EF-Core?
Ich bin der Erstellung einer wiederverwendbaren Bibliothek verwenden .NET Core (targeting .NETStandard 1.4) und ich bin mit Entity Framework Core (und neu für beide). Ich habe eine entity-Klasse, die wie folgt aussieht:
public class Campaign
{
[Key]
public Guid Id { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
public JObject ExtendedData { get; set; }
}
und ich habe einen DbContext-Klasse definiert die DbSet:
public DbSet<Campaign> Campaigns { get; set; }
(Ich bin auch mit dem Repository-Muster mit DI, aber ich denke nicht, dass das relevant ist.)
Meine unit-tests geben mir diese Fehlermeldung:
System.InvalidOperationException: kann Nicht bestimmen die Beziehung
vertreten durch die navigation Eigenschaft 'JToken.Parent' des Typs
'JContainer'. Entweder manuell konfigurieren Sie die Beziehung, oder ignorieren
diese Eigenschaft von dem Modell..
Gibt es eine Möglichkeit zu zeigen, dass dies nicht eine Beziehung, aber gespeichert werden soll, als ein großer string?
ExtendedData
zu string
und speichern Sie dann die stringified JSONIch dachte darüber nach, aber ich möchte, um sicherzustellen, dass es ist immer gültiges JSON.
InformationsquelleAutor Alex | 2017-06-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gehen, um diese Frage zu beantworten anders.
Ideal in das domain-Modell haben sollte, keine Ahnung, wie die Daten gespeichert werden. Hinzufügen von Feldern sichern und zusätzliche
[NotMapped]
Eigenschaften Kupplung ist eigentlich Ihr domain-Modell für Ihre Infrastruktur.Denken Sie daran - Ihre domain ist König, und nicht die Datenbank. Die Datenbank wird gerade verwendet, um zu speichern Teile Ihrer domain.
Stattdessen können Sie verwenden, EF-Core
HasConversion()
Methode auf dieEntityTypeBuilder
- Objekt zu konvertieren zwischen Ihre Art und JSON.Angesichts dieser 2-domain-Modelle:
Habe ich nur Hinzugefügt, Attribute, die der domain interessiert ist - und nicht details, die DB wäre interessiert; I. E es gibt keine
[Key]
.Meinem DbContext hat die folgenden
IEntityTypeConfiguration
für diePerson
:Mit dieser Methode können Sie komplett entkoppeln Sie Ihre Domäne aus Ihrer Infrastruktur. Keine Notwendigkeit für all die backing-field & zusätzliche Eigenschaften.
Wenn ich versuche diese mit JObject bekomme ich einen Mehrdeutiger Treffer gefunden Ausnahme. Etwas über die JObject ist messing witt die überlegung, dass der ef-core verwendet wird.
Wenn ich die [NotMapped] - Attribut, um die JObject Eigenschaft, und fügen Sie dann die Konvertierung scheint es korrekt zu funktionieren
Seien Sie vorsichtig mit diesem Ansatz: EF-Core-Marken, die eine Entität als nur geändert, wenn das Feld zugeordnet ist. Also, wenn Sie
person.Addresses.Add
, die Entität, die nicht gekennzeichnet werden aktualisiert; Sie müssen rufen Sie die Eigenschaft setter -person.Addresses = updatedAddresses
.richtig, Sie würden nicht wollen, setzen auf die out-of-the-box-Funktionalität, kümmert sich um eine Personen-Staat.
InformationsquelleAutor Darren Wainwright
@Michael die Antwort hat mich auf der Strecke aber ich implementierte es ein wenig anders. Ich landete speichern Sie den Wert als string in einem privaten Anwesen und es als "Backing Field". Die ExtendedData Eigentum umgewandelt JObject einen string auf dem set, und Umgekehrt, auf bekommen:
Setzen
_extendedData
als ein Feld sichern, fügte ich diese zu meinem Kontext:Update: Darren Antwort zu verwenden, EF-Core-Wert Umbauten (neue EF-Core 2.1 - die gar nicht die Zeit, diese zu beantworten) zu sein scheint der beste Weg zu gehen an diesem Punkt.
Beide sind richtige Ansatz. Der einzige Unterschied ist, da EF-core unterstützt shadow-Eigenschaften, backing-field-Ansatz nutzen würden, eine shadow-Eigenschaft und vermeiden, dass zusätzliche Eigenschaft in das domain-Modell. 🙂
InformationsquelleAutor Alex
Könnten Sie versuchen, etwas wie dies?
hier ist die migration Ausgabe:
InformationsquelleAutor Michael
Für diejenigen, die sich mit EF 2.1 es ist ein nettes kleines NuGet-Paket EfCoreJsonValueConverter das macht es ziemlich einfach.
InformationsquelleAutor sjclark76
Den Kommentar von @Métoule:
ich mir einen anderen Ansatz, so dass diese Tatsache liegt auf der Hand: die Verwendung von Getter-und Setter - Methoden, eher als eine Eigenschaft.
Theoretisch könnten Sie dies tun:
Aber es ist viel mehr klar, dass dem nicht Tun, Was Sie Denken, Es Macht™.
Wenn Sie Datenbank-erste, und die Art von Klasse auto-generator für die EF, dann die Klassen werden in der Regel erklärt, wie
partial
, so können Sie dieses Zeug in eine separate Datei, die nicht geblasen bekommen das nächste mal, wenn Sie aktualisieren Sie Ihre Klassen aus der Datenbank.InformationsquelleAutor Gabriel Luci