Storing DateTime property instead of byte array in SQL table using Code-First MVC5 EF6

asp.net-mvc-5 c# datetime entity-framework-6 sql

Question

When I try to initialize my database using EF6 in MVC5 I get the error: The property 'Timestamp' is not a Byte array. IsRowVersion can only be configured for Byte array properties. Is there a way I can override the IsRowVersion using FluentAPI or is there another method to store DateTime using MVC5 EF6 or is this simply the result of using the Timestamp data annotation? I prefer to store as DateTime instead of byte array. Just for visualization Model looks like this:

    public class UserProfile : IdentityUser
    {

        //ctor
        public UserProfile()
        {
            Random rnd = new Random();
            int pic = rnd.Next(1, 6); 

            DateJoined = DateTime.Now;
            UserLevel = 4;
            ImageUrl = "/Content/Avatars/Samples/sample" + pic + ".jpg"; // or append .jpg which == .jpg
        }

        public UserProfile(string name, string url)
        {
            UserName = name;
            DateJoined = DateTime.Now;
            UserLevel = 4;
            ImageUrl = url;
            Email = "your@email.com";
        }

        public UserProfile(string name, string url, string email)
        {
            Random rnd = new Random();
            int pic = rnd.Next(1, 6);
            UserName = name;
            DateJoined = DateTime.Now;
            UserLevel = 4;
            ImageUrl = "/Content/Avatars/sample" + pic + ".jpg"; // or append .jpg which == .jpg
            Email = email;
        }
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }
        [Required(ErrorMessage="*Username is required."), RegularExpression(@"^[\p{L} \p{Nd}_]+$")]
         [MinLengthAttribute(5, ErrorMessage="Not enough characters! UserName must be at least 5 chars."), MaxLengthAttribute(30,ErrorMessage="Too many characters in UserName!")]
        public override string UserName { get; set; }
        [Required(ErrorMessage="*Email is required."), EmailAddress, RegularExpression(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*")]
        [DataType(DataType.EmailAddress)]
        [Display(Name = "Email address")]
        public string Email { get; set; }
        [ScaffoldColumn(false),Required]
        public string ImageUrl { get; set; }
        [DisplayFormat(DataFormatString = "{0}")] //{0:d} or {0:D}
        [DataType(DataType.DateTime), Timestamp, ScaffoldColumn(false)] //<--Problem 
        public DateTime DateJoined { get; set; }
        [Range(1, 6), ScaffoldColumn(false)]
        public int UserLevel { get; set; }
        [ScaffoldColumn(false)]
        public int? TotalRepPoints { get; set; }
        [ScaffoldColumn(false)]
        public virtual IDictionary<int, int> TotalPointsByCat { get; set; }
        // int = CategoryId, int = UserRank
        public virtual IDictionary<int, int> Rankings { get; set; }
        public virtual ICollection<Article> Articles { get; set; }
        public virtual ICollection<Answer> Answers { get; set; }
        public virtual ICollection<Vote> Votes { get; set; }
        public virtual ICollection<Question> Questions { get; set; }

    }

When I use NuGet Console:

 PM> Enable-Migrations -Force
Checking if the context targets an existing database...
System.InvalidOperationException: The property 'Timestamp' is not a Byte array. IsRowVersion can only be configured for Byte array properties.
   at System.Data.Entity.ModelConfiguration.Configuration.ConventionPrimitivePropertyConfiguration.IsRowVersion()
   at System.Data.Entity.ModelConfiguration.Conventions.TimestampAttributeConvention.Apply(ConventionPrimitivePropertyConfiguration configuration, TimestampAttribute attribute)
   at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
...
    The property 'Timestamp' is not a Byte array. IsRowVersion can only be configured for Byte array properties.
    PM> 

Thanks in advance!


EDIT

When storing properties using data annotation [DataType(DataType.DateTime)] with DateTime? class you will get datetime type field in SQL.

When storing properties using data annotation [Timestamp] with byte[] you will get timestamp type field in SQL.

enter image description here

1
3
1/3/2015 4:34:55 AM

Accepted Answer

From the Microsoft documentation on timestamp (AKA rowversion) (emphasis added):

Is a data type that exposes automatically generated, unique binary numbers within a database. rowversion is generally used as a mechanism for version-stamping table rows. The storage size is 8 bytes. The rowversion data type is just an incrementing number and does not preserve a date or a time. To record a date or time, use a datetime2 data type.

So this data type, despite its old name, has essentially nothing to do with actual datetime values as we generally think of them.

Pick another column type, like datetime.

4
3/6/2014 4:19:37 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