实体框架通用实体继承id错误 [英] Entity Framework generic entity inheritance id error
问题描述
第2部分问题,从这里继续:
EntityFramework Core - 使用DbUpdateConcurrencyException 更新记录失败
错误:
派生类型BinaryFile不能对属性Id具有KeyAttribute,因为主键只能在根类型上声明。
我是尽可能地为我的实体继承遗产,所以我尽可能地删除重复。
我的继承结构:
public interface IEntityMinimum
{
bool IsDeleted {get;组; }
byte [] Version {get;组; }
string CreatedBy {get;组; }
}
public class EntityMinimum:IEntityMinimum
{
public bool IsDeleted {get;组; }
[Timestamp]
public byte [] Version {get;组; }
public string CreatedBy {get;组;
}
public interface IEntity:IEntityMinimum
{
object Id {get;组; }
DateTime CreatedDate {get;组; }
DateTime? ModifiedDate {get;组; }
string ModifiedBy {get;组; }
}
public interface IEntity< T> :IEntity
{
new T Id {get;组; }
}
public abstract class Entity< T> :EntityMinimum,IEntity< T>
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public T Id {get;组; }
对象IEntity.Id
{
get => ID;
set =>抛出新的NotImplementedException();
}
私人DateTime? _创建日期;
[DataType(DataType.DateTime)]
public DateTime CreatedDate
{
get => _创建日期 ?? DateTime.UtcNow;
set => _createdDate = value;
}
[DataType(DataType.DateTime)]
public DateTime? ModifiedDate {get;组; }
public string ModifiedBy {get;组; }
}
public class EntityMaximum:Entity< int>
{
public bool IsActive {get;组; }
}
public class BinaryFile:EntityMaximum
{
public string Name {get;组; }
public string UniqueName {get;组; }
public Guid UniqueId {get;组; }
public byte [] Content {get;组; }
public virtual ICollection< Campaign>活动{get;组; }
}
当我使用Fluent API禁用<$ c $如下所示: EntityMinimum
类型的版本
中的c> isConcurrencyToken
// https://stackoverflow.com/questions/44009020/entity-framework-isrowversion-without-concurrency-check
builder.Entity< EntityMinimum>()。Property(x => x.Version).IsRowVersion()。IsConcurrencyToken(false);
这是必需的,因为如果我没有禁用 isConcurrencyToken
Microsoft.EntityFrameworkCore。 DbUpdateConcurrencyException:数据库操作期望影响1行,但实际影响0行。数据可能已被修改或删除,因为实体被加载。
如果我删除流畅的api配置,它的工作,但不更新因为版本
字段具有 [TimeStamp]
属性。
我有 [TimeStamp]
将中的版本
EntityMinimum 版本
附加到每个表中,所以我可以使用 TimeStamp
来实现移动和Web数据之间的同步。 p>
我正好做这个结构,或者我应该摆脱 [TimeStamp] byte [] Version
,只需使用字符串,并保存
DateTime
将其刻录到同步目的中。
问题是调用
builder.Entity< EntityMinimum>()
将 EntityMinimum
标记为实体(EF的一部分核心继承策略),而据我所知,您使用基类层次结构仅用于实现目的。
相反,您可以使用EF Core模型元数据服务关闭 IsConcurrencyToken
for 版本
属性从任何真实实体派生自 EntityMinimum
这样:
foreach(modelBuilder.Model.GetEntityTypes()中的var entityType)
{
if(typeof(EntityMinimum).IsAssignableFrom(entityType.ClrType))
entityType.FindProperty(Version)。IsConcurrencyToken = false;
}
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?
The problem is that the call
builder.Entity<EntityMinimum>()
marks the EntityMinimum
class as entity (part of the EF Core inheritance strategy), while as I understand, you use the base class hierarchy just for implementation purposes.
Instead, you could use the EF Core model metadata services to turn off IsConcurrencyToken
for the Version
property of any real entity derived from EntityMinimum
like this:
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
if (typeof(EntityMinimum).IsAssignableFrom(entityType.ClrType))
entityType.FindProperty("Version").IsConcurrencyToken = false;
}
这篇关于实体框架通用实体继承id错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!