如何使用EF保存实体并避免创建新模型?

时间:2019-07-27 12:39:27

标签: c# json xml asp.net-core entity-framework-core

我有一个模特:

public class PersonModel
{
    [Key]
    [JsonProperty("ix")]
    [XmlElement("ix")]
    public int Index { get; set; }

    [XmlElement("content")]
    public ContentModel Content { get; set; }
}

[XmlRoot(ElementName = "content")]
public class ContentModel
{
    [JsonProperty("name")]
    [XmlElement("name")]
    public string Name { get; set; }
    [JsonProperty("visits")]
    [XmlElement("visits", IsNullable = true)]
    public int? Visits { get; set; }
    public bool ShouldSerializeVisits() { return Visits != null; }
    [JsonProperty("date")]
    public DateTime Date { get; set; }

    [XmlElement("date")]
    public string dateRequested
    {
        get { return Date.ToString("yyyy-MM-dd"); }
        set { Date = DateTime.ParseExact(value, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); }
    }
}

他就是这样,因为我想要一棵xml的树,像这样:

<?xml version="1.0" encoding="utf-8"?>
<PersonXmlModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ix>5</ix>
  <content>
    <name>Jadon</name>
    <date>2009-12-21</date>
  </content>
</PersonXmlModel>

但是我也想在使用EF时将对象保存到数据库中:

public void AddItem(PersonModel request)
{
    PersonModel dataItem = new PersonModel
    {
        Index = request.Index,
        Content = new ContentModel
        {
            Name = request.Content.Name,
            Visits = request.Content.Visits,
            Date = request.Content.Date
        }
    };
    _context.Requests.Add(dataItem);
    _context.SaveChanges();
}

并且数据库表具有列:

Index
Name
Visits
Date

table columns

我想知道,是否有任何方法可以使用一些EF属性标记模型的属性,以将对象直接保存到DB并避免使用类似的其他模型?

public class PersonModelDatabase
{
    public int Index { get; set; }
    public string Name { get; set; }
    public int? Visits { get; set; }
    public DateTime Date { get; set; }
}

更新 以下是解决问题的解决方案,但不建议使用DRY。

[Table("Requests")]
    public class PersonModel
    {
        [Key]
        [JsonProperty("ix")]
        [XmlElement("ix")]
        [Column("Index")]
        public int Index { get; set; }
        [Column("Name")]
        public string Name { get; set; }
        [Column("Visits")]
        public int? Visits { get; set; }
        [Column("Date")]
        public DateTime Date { get; set; }

        [XmlElement("content")]
        public ContentModel Content { get; set; }
    }

    [ComplexType]
    [XmlRoot(ElementName = "content")]
    public class ContentModel
    {
        [Key]
        [JsonProperty("name")]
        [XmlElement("name")]
        public string Name { get; set; }
        [JsonProperty("visits")]
        [XmlElement("visits", IsNullable = true)]
        public int? Visits { get; set; }
        public bool ShouldSerializeVisits() { return Visits != null; }
        [JsonProperty("date")]
        public DateTime Date { get; set; }

        [XmlElement("date")]
        public string dateRequested
        {
            get { return Date.ToString("yyyy-MM-dd"); }
            set { Date = DateTime.ParseExact(value, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); }
        }
    }

1 个答案:

答案 0 :(得分:0)

关于 Mat J 的评论和this answer,我使用了答案中的第二种方法。除此之外,我还必须用dateRequested属性标记[NotMapped]。否则,EF会抛出一个异常

  

无效的列名“ ContentModel_dateRequested”。

工作解决方案:

public class PersonModel
    {
        [Key]
        [JsonProperty("ix")]
        [XmlElement("ix")]
        public int Index { get; set; }

        [XmlElement("content")]
        public ContentModel ContentModel { get; set; }
    }

    [ComplexType]//added
    [XmlRoot(ElementName = "content")]
    public class ContentModel
    {
        [JsonProperty("name")]
        [XmlElement("name")]
        public string Name { get; set; }
        [JsonProperty("visits")]
        [XmlElement("visits", IsNullable = true)]
        public int? Visits { get; set; }
        public bool ShouldSerializeVisits() { return Visits != null; }
        [JsonProperty("date")]
        public DateTime Date { get; set; }
        [NotMapped]//added
        [XmlElement("date")]
        public string dateRequested
        {
            get { return Date.ToString("yyyy-MM-dd"); }
            set { Date = DateTime.ParseExact(value, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); }
        }
    }

并在我的ApplicationDbContext类中添加了新方法:

//added
protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<PersonModel>(table =>
        {
            table.OwnsOne(
                x => x.ContentModel,
                content =>
                {
                    content.Property(x => x.Name).HasColumnName("Name");
                    content.Property(x => x.Visits).HasColumnName("Visits");
                    content.Property(x => x.Date).HasColumnName("Date");
                });
        });
    }