Entity object property with a timestamp/rowversion field?

.net c# entity-framework entity-framework-5 entity-framework-6

Question

I am using entity framework 6 and i have a base entity called EntityBase, very simple as so

public abstract class EntityBase : IEntityBase
{
    public virtual long Id { get; set; }
}

Each of my entities inherit from this. Now some entities need audit information, so i have first created an interface called IAudit

public interface IAudit
{
    Audit Audit { get; set; }
}

And the Audit object like so

public class Audit
{
    public bool IsDeleted { get; set; }

    public DateTime? DeletedDate { get; set; }

    public long? DeletedByUserId { get; set; }

    public DateTime CreatedDate { get; set; }

    public long CreatedByUserId { get; set; }

    public DateTime UpdatedDate { get; set; }

    public long UpdatedByUserId { get; set; }

    public byte[] RowVersion { get; set; }
}

And if an entity needs audit information, i apply this interface. Here is an example

public class Attachment : EntityBase, IAudit
{
    #region IAudit

    public Audit Audit { get; set; }

    #endregion

    public string Name { get; set; }
}

I am using code first, so now in my DbContext, i have this in my OnModelCreating method

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

    modelBuilder.Configurations.Add(new AttachmentConfig());
}

Here is my AttachmentConfig file, which inherits from EntityBaseConfig, both included below

public abstract class EntityBaseConfig<TEntity> : EntityTypeConfiguration<TEntity>
    where TEntity : EntityBase
{
    public EntityBaseConfig()
    {
        this.HasKey(e => e.Id);
    }
}

class AttachmentConfig : EntityBaseConfig<Attachment>
{
    public AttachmentConfig()
        : base()
    {
        this.Property(e => e.Name)
            .HasMaxLength(255)
            .IsRequired();

    }
}

Now when my table is created, the Attachment table has the columns i would expect, but Audit_RowVersion is varbinary(max) instead of timestamp.

I have tried to put this line in each config file but get this error.

this.Property(e => e.Audit.RowVersion).IsRowVersion();

Schema specified is not valid. Errors: (36,14) : error 2039: The conceptual side property 'RowVersion' has already been mapped to a storage property with type 'rowversion'. If the conceptual side property is mapped to multiple properties in the storage model, make sure that all the properties in the storage model have the same type.

But i do not want to write this line in each file anyway. How can i get the Audit.RowVersion column to generate as a timestamp, and ideally write it once, so that all objects that implement IAudit also get the configured fields?

EDIT:

I have now added a config file for the Audit object, which looks like this

public class AuditConfig : EntityTypeConfiguration<Audit>
{
    public AuditConfig() : base()
    {
        this.Property(e => e.RowVersion)
            .IsRowVersion();
    }
}

And i call this in the OnModelCreating method, like so, before the other Configuration calls

modelBuilder.Configurations.Add(new AuditConfig());

Now when i run my project, i get the following error

A table can only have one timestamp column. Because table 'Attachment' already has one, the column 'Audit_RowVersion' cannot be added.

If i look at the database and Attachment table created so far, it has the fields in the Audit object, but they do not have the Audit_ prefix? Maybe this is a clue to someone?

1
0
4/17/2015 11:36:29 AM

Popular Answer

You can use DataAnnotations.

In your model class

public class Audit
{
    public bool IsDeleted { get; set; }

    public DateTime? DeletedDate { get; set; }

    public long? DeletedByUserId { get; set; }

    public DateTime CreatedDate { get; set; }

    public long CreatedByUserId { get; set; }

    public DateTime UpdatedDate { get; set; }

    public long UpdatedByUserId { get; set; }

    [TimeStamp]
    public byte[] RowVersion { get; set; }
}

You can add [TimeStamp] Attribute for your variable.

0
4/17/2015 11:39:38 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