How to save entity and avoid creating of new model, using EF?

asp.net-core c# entity-framework-core json xml

Question

I have a model:

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

And he is like that, bacause I want to have xml tree that looks like:

<?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>

But also I want to save the object to the database when using 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();
}

And database table has columns:

Index
Name
Visits
Date

table columns

And I was wondering, is there any way to mark my model's properties with some EF attributes to save the object directly to DB and avoid using some additional model like this?

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

UPDATE Below is a solution that fixes problem, but is against 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
1
7/28/2019 7:22:34 AM

Accepted Answer

Basing on Mat J comments and this answer I used second approach from the answer. Besides this I had this I had to mark dateRequested with [NotMapped] attribute. Otherwise EF was throwing me an exception that

Invalid column name 'ContentModel_dateRequested'.

Working solution:

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

And added new method in my ApplicationDbContext class:

//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");
                });
        });
    }
0
7/30/2019 12:17:35 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow