2017-06-02 125 views
0

第2部分的問題,這從這裏繼續: EntityFramework Core - Update record fails with DbUpdateConcurrencyException實體框架通用實體繼承ID錯誤

錯誤:

The derived type 'BinaryFile' cannot have KeyAttribute on property 'Id' since primary key can only be declared on the root type.

我試圖讓繼承了我的實體儘可能多的,所以我儘可能地去除重複。

我的繼承結構:

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

,當我用流利的API對Version場禁用isConcurrencyTokenEntityMinimum類這樣我得到這個錯誤:

// https://stackoverflow.com/questions/44009020/entity-framework-isrowversion-without-concurrency-check 
    builder.Entity<EntityMinimum>().Property(x => x.Version).IsRowVersion().IsConcurrencyToken(false); 

這是必需的,因爲我如果我不在Version字段上禁用isConcurrencyToken,還有另一個問題:

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.

如果我刪除流利的API配置,它的工作原理,但不會更新,因爲Version字段具有[TimeStamp]屬性。

我在EntityMinimum這個[TimeStamp]Version領域追加Version每一個表,所以我可以使用TimeStamp爲手機和網絡之間的數據同步的目的。

我是否正確地做了這個結構,或者我應該擺脫[TimeStamp] byte[] Version,只是使用字符串Version並保存DateTime滴答作出同步的目的?

+0

什麼請出示使用。即'產品:實體'??? – Seabizkit

回答

2

的問題是,通話

builder.Entity<EntityMinimum>() 

標誌着EntityMinimum類作爲實體(在EF核心產業戰略的一部分),而據我所知,您使用基類層次結構只是實現目的。

相反,你可以使用EF核心模型元數據服務關閉IsConcurrencyTokenEntityMinimum得出這樣的任何真正的實體的財產Version

foreach (var entityType in modelBuilder.Model.GetEntityTypes()) 
{ 
    if (typeof(EntityMinimum).IsAssignableFrom(entityType.ClrType)) 
     entityType.FindProperty("Version").IsConcurrencyToken = false; 
} 
+0

這工作,謝謝。 –