.net EF核心无法保存IDENTITY_INSERT为OFF的实体

edqdpe6u  于 2022-12-30  发布在  .NET
关注(0)|答案(1)|浏览(224)

我有一个模型类Category,它有一个可空的ParentId作为其父类别的引用。我决定使用EF Core 7及其FluentApi将此模型Map到数据库,但我不想使用EF Core迁移,而是手动创建脚本。

CREATE TABLE [Categories] 
(
    [Id] [bigint] IDENTITY(1,1) NOT NULL,       
    [Created] [datetime2](0) NOT NULL,  
    [ParentId] [bigint] NULL,
    [Name] [nvarchar](255) NOT NULL,        

    CONSTRAINT [PK_Categories_Id] 
        PRIMARY KEY CLUSTERED ([Id] ASC)        
)   

ALTER TABLE [Categories] WITH CHECK 
    ADD CONSTRAINT [FK_Cat_Cat] 
        FOREIGN KEY([ParentId]) REFERENCES [Categories] ([Id])

型号等级

public class Category
{    
    public long Id { get; }
    public string Name { get; set; };
    public Category? Parent { get; set; }
    public long? ParentId { get; set; } 
    public ICollection<Category>? Categories { get; set; } = new List<Category>();            
}

EF Core 7Map程序

public class CategoryConfiguration : IEntityTypeConfiguration<Category>
{
    public void Configure(EntityTypeBuilder<Category> builder)
    {
            builder.ToTable("Categories");
            builder.HasKey(it => it.Id);
            builder.Property(it => it.Id).ValueGeneratedNever();
            builder.Property(it => it.Created).IsRequired();            
            builder.Property(it => it.Name).IsRequired();   
            builder.HasOne(it => it.Parent)
                .WithMany(c => c.Categories)
                .HasForeignKey(d => d.ParentId)
                .IsRequired(false);
        }
    }
}

这是应用程序代码。

var parentId = 1;  // id of the previously saved category in the DB
Category? parent = await _repository.GetById(parentId, cancellationToken);
var category = new Category 
{
    Name = "test",
    Parent = parent  //if I leave this line out the save will be successfully created              
};

await _repository.Insert(category);

try
{
    await _repository.SaveAsync();
}
catch (DbUpdateException ex)
{
    // Cannot insert explicit value for identity column in table 'Categories' when IDENTITY_INSERT is set to OFF.
}

您会注意到,在Map器中的Id属性上设置ValueGeneratedNever(),这将是数据库的职责。
我试着在数据库中显式地设置身份:

SET IDENTITY_INSERT [Categories] ON

但我还是得到了
当IDENTITY_INSERT设置为OFF时,无法为表'Categories'中的标识列插入显式值。
更新:在Map类上,我尝试了以下每种方法

-  builder.Property(it => it.Id).UseIdentityColumn(1,1);
-  builder.Property(it => it.Id).UseIdentityColumn();
-  builder.Property(it => it.Id).ValueGeneratedNever();
-  builder.Property(it => it.Id).ValueGeneratedAdd();

但我还是犯了同样的错误。
存储库Insert只是对db上下文add的抽象

public async Task Insert(T entity)
        {
            await _dbContext.Set<T>().AddAsync(entity);
        }
carvr3hs

carvr3hs1#

这是因为默认情况下,实体的Id0,EntityFramework试图在不允许的地方添加值。
试试这个:

builder.HasKey(it => it.Id);
 // NOTE: Never get involved in primary key generation and consider 
 //       they are unique in the domain
 // Remove .ValueGeneratedNever() and use .UseIdentityColumn() instead
 builder.Property(it => it.Id).UseIdentityColumn();

相关问题