web-dev-qa-db-ja.com

コードファーストアプリケーションのXML列

コードファーストでXML列を作成しようとしています。 Entity FrameworkがXML列を完全にサポートしておらず、それらを文字列として読み取ることはよく知っています。それはいいです。ただし、列の型をXMLにしたいのですが。これが私のクラスです:

_class Content
{
    public int ContentId { get; set; }

    [Column(TypeName="xml")]
    public string XmlString { get; set; }

    [NotMapped]
    public XElement Xml { get { ... } set { ... } }
 }
_

問題は、Code First MigrationsがColumn属性を完全に無視し、フィールドをnvarchar(max)として作成することです。 [DataType("xml")]を使ってみましたが、それもうまくいきませんでした。

これは移行のバグですか?

18
zmbq

やってみました:

public String XmlContent { get; set; }

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

public partial class XmlEntityMap : EntityTypeConfiguration<XmlEntity>
{
    public XmlEntityMap()
    {
        // ...
        this.Property(c => c.XmlContent).HasColumnType("xml");

        this.Ignore(c => c.XmlValueWrapper);
    }
}
32
TDaver

属性で必要なことを達成し、モデルクラスのxmlフィールドを属性で装飾しました。

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

これらの2つの記事の助けを得ました:

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/

解決

属性を定義する

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

コンテキストに属性を登録する

コンテキストの「OnModelCreating」で

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

カスタムSQLジェネレーター

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

カスタムSQLジェネレーターを登録する

移行構成コンストラクターで、カスタムSQLジェネレーターを登録します。

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

しかし、XmlContentがnullの場合はどうなりますか?

多分 :

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