将自动增量/ ValueGeneratedOnAdd与EF Core + SQLite一起使用时,“值不能为空”

时间:2020-02-13 00:38:38

标签: .net sqlite asp.net-core .net-core entity-framework-core

我有2个实体MovieMovieVersion继承了以下抽象类,并定义了ID属性:

public interface IEntity
{
    int Id { get; }
}

public abstract class EntityBase : IEntity
{
    public int Id { get; set; }
}

public class Movie : EntityBase, IAggregateRoot ...

public class MovieVersion : EntityBase ...

我已经设置了以下配置:

public class MovieConfiguration : IEntityTypeConfiguration<Movie>
{
    public void Configure(EntityTypeBuilder<Movie> builder)
    {
        builder.HasKey(m => m.Id);

        builder.Property(m => m.Id).ValueGeneratedOnAdd();

        builder.HasMany(m => m.MovieVersions)
            .WithOne();
    }
}

public class MovieVersionConfiguration : IEntityTypeConfiguration<MovieVersion>
{
    public void Configure(EntityTypeBuilder<MovieVersion> builder)
    {
        builder.HasKey(m => m.Id);

        builder.Property(m => m.Id).ValueGeneratedOnAdd();
    }
}

我尝试使用以下代码作为种子:

var movieRepository = new MovieRepository(context);
var movie = new Movie("The Good, the Bad and the Ugly", 1966);
movieRepository.AddMovie(movie);

我得到这个错误:“值不能为空。(参数'key')”。有什么地方出问题了?我以为以前可以使用它,但是现在情况有所改变。我使用的是EF Core v3.1.1,并使用SQLite。

出于完整性考虑,以下是存储库摘录:

public abstract class RepositoryBase<T> where T : class, IAggregateRoot
{
    private readonly ApplicationDbContext _context;

    public RepositoryBase(ApplicationDbContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    protected DbSet<T> Set => _context.Set<T>();
}

public class MovieRepository : RepositoryBase<Movie>, IMovieRepository
{
    public MovieRepository(ApplicationDbContext context) : base(context) {}

    public void AddMovie(Movie movie)
    {
        Set.Add(movie);
    }
}

DbContext:

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    public DbSet<Movie> Movies { get; set; }

    public DbSet<MovieVersion> MovieVersions { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());

        base.OnModelCreating(builder);
    }
}

种子:

context.Database.EnsureCreated();

if (context.Movies.Any()) return;

var movieRepository = new MovieRepository(context);
var movieContainerRepository = new MovieContainerRepository(context);

var movie = new Movie("The Good, the Bad and the Ugly", 1966);
movieRepository.AddMovie(movie); // throws mentioned error

提前谢谢!

2 个答案:

答案 0 :(得分:0)

您的实体界面没有设置器,也许您应该考虑像这样更改它

public interface IEntity
{
    int Id { get; set;}
}

答案 1 :(得分:0)

我认为您正在使用没有标识列的sql lite。在sql lite中是AUTOINCREMENT 使用权框架 要使用SQLite数据库提供程序,第一步是安装Microsoft.EntityFrameworkCore.Sqlite NuGet程序包。

或执行手动校正表的方式 EF使用SQL语法查找数据库并创建标识列。 删除您的数据迁移。 尝试像这样更改表格。

CREATE TABLE COMPANY(
   ID INTEGER PRIMARY KEY AUTOINCREMENT,
   NAME           TEXT      NOT NULL,
   AGE            INT       NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);
相关问题