实体框架通用实体继承id错误 [英] Entity Framework generic entity inheritance id error

查看:407
本文介绍了实体框架通用实体继承id错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

第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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆