实体框架通用实体继承 ID 错误



第 2 部分问题,从这里继续: EntityFramework Core - 更新记录失败,并显示 DbUpdateConcurrencyException

错误:

派生类型"二进制文件"不能在属性"Id"上具有键属性,因为主键只能在根类型上声明。

我正在尝试尽可能多地为我的实体进行继承,因此我尽可能多地删除重复项。

我的继承结构:

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 禁用EntityMinimum类的Version字段上的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 行。自加载实体以来,数据可能已被修改或删除。

如果我删除流畅的 api 配置,它可以工作,但由于Version字段具有[TimeStamp]属性而不会更新。

我在EntityMinimum有这个[TimeStamp]Version字段,可以将Version附加到每个表,因此我可以将TimeStamp用于移动数据和 Web 数据之间的同步目的。

我是否正确地执行了此结构,或者我应该摆脱[TimeStamp] byte[] Version,只使用字符串Version并将DateTime刻度保存到其中以进行同步?

问题是调用

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

最新更新