7

Beispiel: Sagen wir, ich habe diese drei Klassen. Foo ist eine richtige Entity Framework-Entität mit einem DbSet, während ich möchte, dass mein EF DbContext keine Kenntnis von Bar und Baz hat, weil ich die Foo's Bar-Eigenschaft mit meinem erfundenen SerializedColumn-Attribut markiert habe. Wenn ich dieses Attribut anwende, möchte ich, dass EF die Instanz von Bar mit seinen Bazes in ein einzelnes String-Feld serialisiert und Bar transparent zu einem Bar-Objekt deserialisiert, wenn ein Foo durch EF materialisiert wird.Fortsetzen und Abrufen von serialisierten Entitätseigenschaften mit Entity Framework 6.1 Code zuerst

public class Foo 
{ 
    public Guid Id { get; set; } 
    [SerializedColumn] 
    public Bar Bar { get; set; } 
    // .. 
} 

public class Bar 
{ 
    public string Name { get; set; } 
    public Baz[] Baz { get; set; } 
    // .. 
} 

public class Baz 
{ 
    public string Name { get; set; } 
    // .. 
} 

So würde Foo Tabellenspalten wie folgt aussehen:

[Id] [uniqueidentifier] NOT NULL 
[Bar] [nvarchar](max) NULL 

Und wenn ich eine Foo Abfrage ich wieder eins mit dem Bar Eigenschaft bereits deserialisiert. Wenn ich eine Foo einfüge oder aktualisiere, wird die Bar-Eigenschaft von EF serialisiert, ohne dass ich darüber nachdenken muss. Das einzige, was ich tun muss, ist das Hinzufügen des [SerializeColumn] Attributs zu Eigenschaften.

Ziele:

  • Ich bin nicht unbedingt für eine Blas- Lösung suchen (obwohl ich würde es akzeptieren), aber für die Führung ab, wo in EF-Pipeline zu springen, und wie das zu tun. I.E. Welche EF-Klassen, Konfigurationen, Konventionen usw. muss ich berücksichtigen?
  • Ich möchte Migrationen generiert werden, wie man erwarten würde. Das heißt, ich möchte nicht, dass sich meine Bar-Eigenschaft in ein "Bar_Id" -Feld verwandelt, das auf eine "Bar" -Tabelle zeigt. Stattdessen möchte ich ein nvarchar(max) "Bar" -Feld, das die serialisierte Version eines Bar Objekts enthalten wird. Wenn dies nicht möglich ist, sagen Sie dies bitte in Ihrer Antwort.

Hinweise:

  • Die Idee dazu kam, nachdem die Building Applications with Entity Framework 6 Video von Rowan Miller beobachten.
  • ComplexType dient nicht meine Bedürfnisse. Ich brauche eine tiefe Serialisierung und muss nicht in der Lage sein, irgendwelche Eigenschaften von dem, was serialisiert wurde, zu filtern oder zu sortieren.
  • Ich plane Serialisierung mit Newtonsoft JSON-Bibliothek, aber wie Serialisierung passiert ist nicht wirklich wichtig.
+0

So etwas wie das? http://stackoverflow.com/questions/14779740/can-embed-an-object-in-e-ef-entity-serialize-on-save-deserialize-on-access – MutantNinjaCodeMonkey

+0

@ MutantNinjaCodeMonkey Ich habe das getan die Vergangenheit und es funktioniert, aber ich versuche, Persistenz völlig transparent zu machen. Das ist nur eine Eigenschaft 'Bar' mit meinem zusammengesetzten' SerializeColumnAttribute' und keiner 'BarSerialized' Eigenschaft. –

+2

Ziemlich sicher, dass dies in EF6 nicht möglich ist. Was Sie wirklich brauchen, ist ein Kundentypkonverter.Diese Funktion ist [geplant] (https://github.com/aspnet/EntityFramework/issues/242) für EF7, aber noch nicht implementiert. – DavidG

Antwort

9

Die einzige Lösung ist das,

public class Foo 
{ 
    public Guid Id { get; set; } 

    // Not Mapped attribute will make EF 
    // ignore this property completely 
    [NotMapped] 
    public Bar BarObject { 
     get; 
     set; 
    } 

    public string Bar{ 
     get{ 
      return JsonConvert.Serialize(BarObject); 
     } 
     set{ 
      BarObject = JsonConvert.Deserialize<BarObject>(value); 
     } 
    } 
} 

Aktualisiert gemäß Vorschlag von @zds

+0

Danke Akash, aber ich habe @Bubi das Kopfgeld gegeben, da er zuerst mit im Wesentlichen der gleichen Antwort antwortete wie du, wenn auch etwas weniger detailliert. Wenn ich könnte, hätte ich das Kopfgeld zwischen beiden Antworten geteilt. –

+1

Könnte es besser sein, die Serialisierungslogik in die Eigenschaft 'public string bar' zu verschieben. Nicht die ganze Zeit serialisieren und deserialisieren, wenn etwas geändert wird. Oder fehlt mir etwas? – zds

1

Keine Möglichkeit, dies ohne Änderung von EF zu tun. Mit EF 6 glaube ich, dass mehrere Leute es mit einem Text-Hintergrund-Feld und einigen Einschränkungen (Bar und Bar Kinder hat keinen Zugriff auf EF Persistent Eigenschaft oder Sie benötigen andere Arbeit nach Deserialisierung).

+0

Ich würde mit den Einschränkungen gut umgehen, die mit einem Textunterstützungsfeld in der Datenbank kommen (keine Filterung, In-Datenbank-Projektionen usw.). Oder beziehen Sie sich als Textunterstützungsfeld auf die Verwendung von zwei Eigenschaften, von denen eine mit [NotMapped] markiert ist, bei der es sich um die entschlüsselte Version der verschlüsselten Eigenschaft im Speicher handelt, die EF beibehalten wird? –

+0

Für das Backing-Feld meine ich zwei Eigenschaften, eine mit [NotMapped], die die entschlüsselte In-Memory-Version der verschlüsselten Eigenschaft ist, die EF beibehalten wird. – bubi

+0

Nun, nichts ist falsch mit Backing-Eigenschaften, wenn es darum geht. Danke @bubi Ich werde dieses Bounty ein wenig länger verweilen lassen, um zu sehen, ob jemand anderes hilfreiche Informationen hinzufügen kann. –

Verwandte Themen