Colonne XML in un’applicazione Code-First

Sto cercando di creare una colonna XML in Code First. So bene che Entity Framework non supporta completamente le colonne XML e che le legge come una stringa. Va bene. Mi piacerebbe comunque che il tipo di colonna fosse XML, comunque. Ecco la mia class:

class Content { public int ContentId { get; set; } [Column(TypeName="xml")] public string XmlString { get; set; } [NotMapped] public XElement Xml { get { ... } set { ... } } } 

Il problema è, che Code First Migrations ignora completamente l’attributo Column e crea il campo come nvarchar(max) . Ho provato a usare [DataType("xml")] , ma anche quello non ha funzionato.

È un bug di migrazione?

Hai provato:

 public String XmlContent { get; set; } public XElement XmlValueWrapper { get { return XElement.Parse(XmlContent); } set { XmlContent = value.ToString(); } } public partial class XmlEntityMap : EntityTypeConfiguration { public XmlEntityMap() { // ... this.Property(c => c.XmlContent).HasColumnType("xml"); this.Ignore(c => c.XmlValueWrapper); } } 

Ho raggiunto ciò che è necessario con un attributo e ho decorato il mio campo xml della class del modello con l’attributo.

 [XmlType] public string XmlString { get; set; } [NotMapped] public XElement Xml { get { return !string.IsNullOrWhiteSpace(XmlString) ? XElement.Parse(XmlString) : null; } set { XmlString = value == null ? null : value.ToString(SaveOptions.DisableFormatting); } } 

Ho l’aiuto di questi 2 articoli:

https://entityframework.codeplex.com/wikipage?title=Code%20First%20Annotations

https://andy.mehalick.com/2014/02/06/ef6-adding-a-created-datetime-column-automatically-with-code-first-migrations/

Soluzione

Definisci attributo

 [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public class XmlType : Attribute { } 

Registrare l’attributo nel contesto

In “OnModelCreating” del contesto

 modelBuilder.Conventions.Add(new AttributeToColumnAnnotationConvention("XmlType", (p, attributes) => "xml")); 

Generatore Sql personalizzato

 public class CustomSqlGenerator : SqlServerMigrationSqlGenerator { protected override void Generate(ColumnModel column, IndentedTextWriter writer) { SetColumnDataType(column); base.Generate(column, writer); } private static void SetColumnDataType(ColumnModel column) { // xml type if (column.Annotations.ContainsKey("XmlType")) { column.StoreType = "xml"; } } } 

Registra generatore Sql personalizzato

Nel costruttore della configurazione di migrazione, registrare il generatore SQL personalizzato.

  SetSqlGenerator("System.Data.SqlClient", new CustomSqlGenerator()); 

Ma cosa succede se XmlContent è nullo ??

Può essere :

  public XElement XmlValueWrapper { get { return XmlContent != null ? XElement.Parse(XmlContent) : null; } set { XmlContent = value.ToString(); } }