【问题标题】:Entity Framework generic entity inheritance id error实体框架通用实体继承 id 错误
【发布时间】:2017-06-02 09:57:07
【问题描述】:

第 2 部分问题,从这里继续: EntityFramework Core - Update record fails with DbUpdateConcurrencyException

错误:

派生类型“BinaryFile”不能在属性“Id”上具有 KeyAttribute,因为主键只能在根类型上声明。

我正在尝试尽可能地为我的实体进行继承,所以我尽可能地删除了重复。

我的继承结构:

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

当我使用 Fluent API 在 Version 字段上为 EntityMinimum 禁用 isConcurrencyToken 时出现此错误,如下所示:

    // 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:数据库操作预计会影响 1 行,但实际上影响了 0 行。自加载实体后,数据可能已被修改或删除。

如果我删除 fluent api 配置,它可以工作,但不会更新,因为 Version 字段具有 [TimeStamp] 属性。

我在EntityMinimum 中有这个[TimeStamp] Version 字段以将Version 附加到每个表中,因此我可以使用TimeStamp 在移动数据和网络数据之间进行同步。

我是否正确地执行了这个结构,或者我应该摆脱 [TimeStamp] byte[] Version 并只使用字符串 Version 并保存 DateTime 标记以用于同步目的?

【问题讨论】:

  • 请显示使用情况。即Product: Entity&lt;Product&gt; ???

标签: c# entity-framework inheritance entity-framework-core


【解决方案1】:

问题在于调用

builder.Entity<EntityMinimum>()

EntityMinimum 类标记为实体(EF Core 继承策略的一部分),而据我了解,您使用基类层次结构只是为了实现目的。

相反,您可以使用 EF Core 模型元数据服务为派生自 EntityMinimum 的任何真实实体的 Version 属性关闭 IsConcurrencyToken,如下所示:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-19
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    相关资源
    最近更新 更多