Part 2 problem, which continues from here: EntityFramework Core - Update record fails with DbUpdateConcurrencyException
Error:
The derived type 'BinaryFile' cannot have KeyAttribute on property 'Id' since primary key can only be declared on the root type.
I am trying to make inheritance for my entities as much as possible, so I remove duplication as much as possible.
My inheritance structure:
public interface IEntityMinimum
{
bool IsDeleted { get; set; }
byte[] Version { get; set; }
string CreatedBy { get; set; }
}
public class EntityMinimum : IEntityMinimum
{
public bool IsDeleted { get; set; }
[Timestamp]
public byte[] Version { get; set; }
public string CreatedBy { get; set; }
}
public interface IEntity : IEntityMinimum
{
object Id { get; set; }
DateTime CreatedDate { get; set; }
DateTime? ModifiedDate { get; set; }
string ModifiedBy { get; set; }
}
public interface IEntity<T> : IEntity
{
new T Id { get; set; }
}
public abstract class Entity<T> : EntityMinimum, IEntity<T>
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public T Id { get; set; }
object IEntity.Id
{
get => Id;
set => throw new NotImplementedException();
}
private DateTime? _createdDate;
[DataType(DataType.DateTime)]
public DateTime CreatedDate
{
get => _createdDate ?? DateTime.UtcNow;
set => _createdDate = value;
}
[DataType(DataType.DateTime)]
public DateTime? ModifiedDate { get; set; }
public string ModifiedBy { get; set; }
}
public class EntityMaximum : Entity<int>
{
public bool IsActive { get; set; }
}
public class BinaryFile : EntityMaximum
{
public string Name { get; set; }
public string UniqueName { get; set; }
public Guid UniqueId { get; set; }
public byte[] Content { get; set; }
public virtual ICollection<Campaign> Campaigns { get; set; }
}
I get this error when I use Fluent API to disable isConcurrencyToken on the Version field for the EntityMinimum class like this:
// https://stackoverflow.com/questions/44009020/entity-framework-isrowversion-without-concurrency-check
builder.Entity<EntityMinimum>().Property(x => x.Version).IsRowVersion().IsConcurrencyToken(false);
This is required because I had another issue if I do not disable isConcurrencyToken on the Version field:
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded.
If I remove fluent api configuration, it works, but doesn't update because of Version field which has [TimeStamp] attribute.
I have this [TimeStamp] Version field in EntityMinimum to append Version to every table, so I can use TimeStamp for synchronisation purposes between mobile and web data.
Am I doing this structure correctly, or should I get rid of [TimeStamp] byte[] Version and just use string Version and save DateTime ticks into it for synchronisation purpose?
Product: Entity<Product>???