c# - Entity Framework Core 接收 0 以作为 Id 播种,尽管我将其定义为其他内容
问题描述
尝试添加迁移时,ef core 给我以下错误:
无法添加实体类型“MyEntity”的种子实体,因为属性“Id”需要非零值。考虑提供一个负值以避免与非种子数据发生冲突。
实体 MyEntity 及其超类/接口:
public class MyEntity: EntityObject
{
public long OrderId { get; set; }
public List<StateChange> StateChanges { get; set; }
}
public class EntityObject : IEntityObject
{
[Key]
public int Id { get; set; }
[Timestamp]
public byte[] RowVersion
{
get;
set;
}
}
public class IEntityObject
{
int Id { get; set;
byte[] RowVersion { get; set; }
}
播种:
var seed = new MyEntity{ Id = -2, StateChanges = new List<StateChange>(), OrderId = -2 };
modelBuilder.Entity<MyEntity>().HasData(seed);
我一直在尝试使用 [Key] 和 [DatabaseGenerated] 进行各种尝试,但找不到解决方案。所有ef core nuget依赖的版本都是3.1.5
解决方案
将类 更改IEntityObject
为接口。
这是一个完全正常工作的控制台项目,假设它StateChange
是您的一些内部类,而不是模型/实体类:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace IssueConsoleTemplate
{
public interface IEntityObject // <-- changed from `class` to `interface`
{
int Id { get; set; }
byte[] RowVersion { get; set; }
}
public class EntityObject : IEntityObject
{
[Key]
public int Id { get; set; }
[Timestamp]
public byte[] RowVersion
{
get;
set;
}
}
public class MyEntity : EntityObject
{
public long OrderId { get; set; }
public List<StateChange> StateChanges { get; set; }
}
public class StateChange
{
}
public class Context : DbContext
{
public DbSet<MyEntity> MyEntities { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer(@"Data Source=.\MSSQL14;Integrated Security=SSPI;Initial Catalog=So62865284")
.UseLoggerFactory(
LoggerFactory.Create(
b => b
.AddConsole()
.AddFilter(level => level >= LogLevel.Information)))
.EnableSensitiveDataLogging()
.EnableDetailedErrors();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>(
entity =>
{
entity.Ignore(e => e.StateChanges); // <-- ignore your internal class
entity.HasData(
new MyEntity
{
Id = 2,
StateChanges = new List<StateChange>(),
OrderId = 2
});
});
}
}
internal static class Program
{
private static void Main()
{
using var context = new Context();
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var myEntitiesWithStateChanges = context.MyEntities
.OrderBy(i => i.Id)
.ToList();
Debug.Assert(myEntitiesWithStateChanges.Count == 1);
}
}
}
如果StateChange
它也应该是一个模型类/实体,那么你应该向它添加一个外键并设置关系。这可能看起来像这样:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace IssueConsoleTemplate
{
public interface IEntityObject // <-- changed from `class` to `interface`
{
int Id { get; set; }
byte[] RowVersion { get; set; }
}
public class EntityObject : IEntityObject
{
[Key]
public int Id { get; set; }
[Timestamp]
public byte[] RowVersion
{
get;
set;
}
}
public class MyEntity : EntityObject
{
public long OrderId { get; set; }
public List<StateChange> StateChanges { get; set; } = new List<StateChanges>();
}
public class StateChange : EntityObject
{
public int MyEntityId { get; set; } // <-- added FK
public MyEntity MyEntity { get; set; } // <-- added navigation property
}
public class Context : DbContext
{
public DbSet<MyEntity> MyEntities { get; set; }
public DbSet<StateChange> StateChanges { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer(@"Data Source=.\MSSQL14;Integrated Security=SSPI;Initial Catalog=So62865284")
.UseLoggerFactory(
LoggerFactory.Create(
b => b
.AddConsole()
.AddFilter(level => level >= LogLevel.Information)))
.EnableSensitiveDataLogging()
.EnableDetailedErrors();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>(
entity =>
{
// Added the relationship definition (not really necessary here,
// because this would also work by convention).
entity.HasMany(e => e.StateChanges)
.WithOne(s => s.MyEntity)
.HasForeignKey(s => s.MyEntityId);
entity.HasData(
new MyEntity
{
Id = 2,
OrderId = 2
});
});
modelBuilder.Entity<StateChange>(
entity =>
{
entity.HasData(
new StateChange
{
Id = 2,
MyEntityId = 2,
});
});
}
}
internal static class Program
{
private static void Main()
{
using var context = new Context();
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var myEntitiesWithStateChanges = context.MyEntities
.Include(e => e.StateChanges)
.OrderBy(i => i.Id)
.ToList();
Debug.Assert(myEntitiesWithStateChanges.Count == 1);
Debug.Assert(myEntitiesWithStateChanges[0].StateChanges.Count == 1);
}
}
}
推荐阅读
- ldap - 从 UnboundId LDAP 搜索结果中删除用户的密码
- c++ - 删除带有向量的类
在 C++ 中 - phpunit - 如何使用 ddev 运行 TYPO3 功能测试?
- mysql - Angular 应用程序如何通过本地服务器访问数据库?
- sourced - 执行“sourced init”时“超出上下文截止日期”
- excel - 立即将单元格的值从 EX: 755 更改为 7:55
- typescript - typescript 可以自动检测短路评估吗?
- scala - 阅读 csv 时,转义引号在 spark 2.2.0 中不起作用
- c++ - 使用 `auto` 参数将 Qt5 信号连接到 C++14 Lambda 是否危险?
- python - 使用模块 os 和 sys 在 python 中的索引错误