21

我正在尝试在 Code First 中创建一个 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 迁移完全忽略了 Column 属性并将字段创建为nvarchar(max). 我尝试使用[DataType("xml")],但这也不起作用。

这是迁移错误吗?

4

4 回答 4

39

你有没有尝试过:

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);
    }
}
于 2012-10-01T14:20:33.440 回答
6

我通过属性实现了所需的功能,并用该属性装饰了我的模型类 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());
于 2016-04-01T16:39:12.473 回答
4

现在可以在 Entity Framework Core 2.1+ 中使用 SQL Server XML 列类型和值转换来实现这一点,而无需额外的属性。

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

    public XElement Xml { get; set; }
}

internal class ContentEntityTypeConfiguration : IEntityTypeConfiguration<Content>
{
    public void Configure(EntityTypeBuilder<Content> builder)
    {
        builder.HasKey(e => e.ContentId);

        builder.Property(e => e.ContentId)
            .ValueGeneratedOnAdd();

        builder.Property(e => e.Xml)
            .HasConversion(
                xml => xml.ToString(),
                xml => xml != null ? XElement.Parse(xml) : null)
            .HasColumnType("xml");
    }
}

public class MyDbContext : DbContext
{
    public DbSet<Content> Contents { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfiguration(new ContentEntityTypeConfiguration());
    }
}
于 2020-06-18T10:30:37.883 回答
0

但是如果 XmlContent 为 null 怎么办?

也许 :

    public XElement XmlValueWrapper
    {
        get { return XmlContent != null ? XElement.Parse(XmlContent) : null; }
        set { XmlContent = value.ToString(); }
    }
于 2014-03-17T21:42:08.433 回答