EF Core为标识列插入显式值

Dan*_*san 3 c# entity-framework-core .net-core

我有问题将数据插入到具有外键的数据库表.我正在犯错误

当IDENTITY_INSERT设置为OFF时,无法在表'MachineTypes'中为identity列插入显式值.当IDENTITY_INSERT设置为OFF时,不能在表'SpareTypes'中插入identity列的显式值.

BaseEntity.cs

public abstract class BaseEntity
{
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public Int64 Id { get; set; }

    public DateTime CreateDate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

MachineType.cs

public class MachineType : BaseEntity
{
    [Required]
    [StringLength(50)]
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

SpareType.cs

   public class SpareType : BaseEntity
    {
        [Required]
        [StringLength(25)]
        public string Name { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

SparePart.cs

public class SparePart : BaseEntity
{
[Required]
[StringLength(100)]
public string InternalCode { get; set; }

[StringLength(4096)]
public string Description { get; set; }

[StringLength(255)]
public string NameOnFolder { get; set; }

public decimal? Enter { get; set; }

public decimal? Exit { get; set; }

public decimal? Thickness { get; set; }

public string Band { get; set; }

public string Color { get; set; }

public bool Elastic { get; set; }

[Required]
public virtual MachineType MachineType { get; set; }

[Required]
public virtual SpareType SpareType { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

SparePartViewModel.cs

 public class SparePartViewModel
    {
        public int Id { get; set; }

        public DateTime CreateDate { get; set; }

        [Required]
        [StringLength(100)]
        public string InternalCode { get; set; }

        [StringLength(4096)]
        public string Description { get; set; }

        [StringLength(255)]
        public string NameOnFolder { get; set; }

        public decimal? Enter { get; set; }

        public decimal? Exit { get; set; }

        public decimal? Thickness { get; set; }

        public string Band { get; set; }

        public string Color { get; set; }

        public bool Elastic { get; set; }



        [Required]
        public virtual MachineType MachineType { get; set; }

        [Required]
        public virtual SpareType SpareType { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

发布控制器

[Route("/api/v1/items")]
public class SparePartController : Controller
{
private IRepository<SparePart> _repoSparePart;


public SparePartController(IRepository<SparePart> repoSparePart)
{
    _repoSparePart = repoSparePart;

}

[HttpPost("")]
public async Task<IActionResult> Post([FromBody]SparePartViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        var newItem = Mapper.Map<SparePart>(viewModel);
        newItem.CreateDate = DateTime.Now;

        _repoSparePart.Insert(newItem);

        if (await _repoSparePart.SaveChangesAsync())
        {
            return Created($"items/{newItem.InternalCode}", Mapper.Map<SparePartViewModel>(viewModel));
        }
    }
    return BadRequest("Failed to save.");
}
Run Code Online (Sandbox Code Playgroud)

}

AppContext.cs

   public class AppContext : IdentityDbContext<ApplicationUser>
    {
        private IConfigurationRoot _config;

        public AppContext(IConfigurationRoot config, DbContextOptions options) : base(options)
        {
            _config = config;
        }

        public DbSet<SpareType> SpareTypes { get; set; }
        public DbSet<MachineType> MachineTypes { get; set; }
        public DbSet<SparePart> SpareParts { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.Entity<SpareType>()
                .HasIndex(s => new { s.Name })
                .IsUnique(true);

            builder.Entity<MachineType>()
                .HasIndex(s => s.Name)
                .IsUnique(true);


            base.OnModelCreating(builder);
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
            optionsBuilder.UseSqlServer(_config["ConnectionStrings:RndDbContextConnection"]);
        }
    }
Run Code Online (Sandbox Code Playgroud)

在发布期间,所有数据都被正确捕获,但是什么时候应该插入到数据库中我得到一个错误. 在此输入图像描述

小智 6

插入新的SparePart实例时,需要事先从相同的DbContext中获取MachineType和SpareType引用.否则EF认为您正在尝试创建新的MachineType和SpareType.并且因为设置了Id字段,所以数据库将不允许插入.像这样的东西:

newItem.MachineType = _context.MachineTypes.Find(<some_id>);
newItem.SpareType = _context.SpareTypes.Find(<some_id>);
context.SpareParts.Add(newItem);
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

您可以做的另一件事是在模型上公开外键,然后在将它添加到DbSet之前将其设置在新实例上就足够了.在SparePart中:

[ForeignKey("MachineType")]
public Int64 MachineTypeId { get; set; }

[ForeignKey("SpareType")]
public Int64 SpareTypeId{ get; set; }
Run Code Online (Sandbox Code Playgroud)