Neil Stevens
Neil Stevens

Reputation: 3914

Storing System.Version in database with Entity Framework Code First

I have a database that is created using Entity Framework 6.1 Code First, I have one specific table I am having issues with.

I have a table called Manifests, the entity definition is below

public class Manifest
{
    public int Id { get; set; }
    public DateTime ReleaseDate { get; set; }
    public int VersionMajor { get; set; }
    public int VersionMinor { get; set; }
    public int VersionBuild { get; set; }
    public int VersionRevision { get; set; }
    public Version Version
    {
        get
        {
            return new Version(this.VersionMajor, this.VersionMinor, this.VersionBuild, this.VersionRevision);
        }

        set
        {
            this.VersionMajor = value.Major;
            this.VersionMinor = value.Minor;
            this.VersionBuild = value.Build;
            this.VersionRevision = value.Revision;
        }
    }
    public string ReleaseNotes { get; set; }
    public bool IsCompulsory { get; set; }
    public string Description { get; set; }
    public string UpdatePackage { get; set; }
}

You will notice that I have a property defined which is a System.Version and will store the manifest version, however, when I run add-migration in the package manager console the resulting migration does not include the Version column. I have tried setting the modelBuilder.ComplexType<System.Version>() in OnModelCreating but to no avail, please help?

As suggested I have changed the entity definition (see above), but I am now getting an error when running the seed, please see below:

System.Data.Entity.Core.EntityCommandCompilationException: An error occurred while preparing the command definition. See the inner exception for details. ---> System.Data.Entity.Core.MappingException: 
(6,10) : error 3004: Problem in mapping fragments starting at line 6:No mapping specified for properties Manifest.Version in Set Manifests.
An Entity with Key (PK) will not round-trip when:
  Entity is type [Drogo.Meera.Data.Context.Manifest]

The seed method has the following:

context.Manifests.AddOrUpdate(
    p => p.Version,
    new Manifest
        {
            Description = "Initial Release",
            VersionMajor = 1,
            VersionMinor = 0,
            VersionBuild = 0,
            IsCompulsory = true,
            ReleaseDate = DateTime.Now,
            ReleaseNotes = "Initial Release",
            UpdatePackage = @"v1-0-0\v1-0-0.zip"
        });
context.SaveChanges();

Upvotes: 4

Views: 3721

Answers (2)

Ali Borjian
Ali Borjian

Reputation: 1108

Simply save it in string format and cast it to Version whenever you want.

 try {
     Version ver = Version.Parse("1.2.3");
     Console.WriteLine("Converted '{0} to {1}.", input, ver);
  }
catch (ArgumentNullException) {
         Console.WriteLine("Error: String to be parsed is null.");
      }

Upvotes: 0

jjj
jjj

Reputation: 4997

I think you're not seeing what you're expecting when you're using System.Version as a complex type since it doesn't have any valid properties for EF to use.

If a property has only a getter or a setter, but not both, it will not be included in the model.

https://www.safaribooksonline.com/library/view/programming-entity-framework/9781449317867/ch05s07.html


You should be able to work around this by pulling out the properties you want to keep yourself (and marking Manifest.Version as a property to ignore).

public class Manifest
{
    // other properties

    int VersionMajor { get; set; }
    int VersionMinor { get; set; }
    int VersionBuild { get; set; }
    int VersionRevision { get; set; }

    public Version Version 
    {
        get 
        { 
            return new Version(VersionMajor, VersionMinor, VersionBuild, VersionRevision); 
        }
        set
        {
            VersionMajor = value.Major;
            VersionMinor = value.Minor;
            VersionBuild = value.Build;
            VersionRevision = value.Revision;
        }
    }
}
// Adding [NotMapped] to Manifest.Version would also work, as in the link below
modelBuilder.Entity<Manifest>().Ignore(m => m.Version);

There's another example here: Entity Framework map multiple columns to C# complex type

Upvotes: 4

Related Questions