首页 > 解决方案 > 无法将数据保存到 Db 中,因为 Identity Insert 设置为关闭

问题描述

我已经查看了有关此问题的几个问题,但其中许多问题可以通过快速类注释来解决,但我正在为我的类文件使用元数据,因此我必须使用模型构建器从类中配置我的数据库中的关系。我已经知道问题出在哪里,我的表中无法插入 Id 数据,但我不确定在当前场景中如何更改它,因为我正在使用元数据。我将通过下面的代码向您展示为什么这是不同的。

这是我的代码。

public class CrayonDbContext : DbContext
        {
            private const string connectionString = @"myserver";
    
            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            {
                optionsBuilder.UseSqlServer(connectionString);
            }
    
            public DbSet<BillingStatement> BillingStatements { get; set; }
    
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
    
                modelBuilder.Entity<BillingStatement>().OwnsOne<Price>(s => s.TotalSalesPrice);
                modelBuilder.Entity<BillingStatement>().OwnsOne<ObjectReference>(s => s.InvoiceProfile);
                modelBuilder.Entity<BillingStatement>().OwnsOne<ObjectReference>(s => s.Organization);

                base.OnModelCreating(modelBuilder);
            }
        }

这是来自 CrayonApi NuGet 包的元数据中的 BillingStatement

namespace Crayon.Api.Sdk.Domain.Csp
{
    public class BillingStatement
    {
        public BillingStatement();

        public int Id { get; set; }
        public Price TotalSalesPrice { get; set; }
        public ObjectReference InvoiceProfile { get; set; }
        public ObjectReference Organization { get; set; }
        public DateTimeOffset StartDate { get; set; }
        public DateTimeOffset EndDate { get; set; }
        public ProvisionType ProvisionType { get; set; }
    }
}

现在这里是来自先前显示的账单类的引用类。

public class Price
{
    public Price();

    public decimal Value { get; set; }
    public string CurrencyCode { get; set; }
}

public class ObjectReference
{
    public ObjectReference();

    public int Id { get; set; }
    public string Name { get; set; }
}

public enum ProvisionType
{
    None = 0,
    Seat = 1,
    Usage = 2,
    OneTime = 3,
    Crayon = 4,
    AzureMarketplace = 5
}

这是正在生成的当前表。

CREATE TABLE [BillingStatement] (
      [Id] int NOT NULL IDENTITY,
      [TotalSalesPrice_Value] decimal(18,2) NULL,
      [TotalSalesPrice_CurrencyCode] nvarchar(max) NULL,
      [InvoiceProfile_Id] int NULL,
      [InvoiceProfile_Name] nvarchar(max) NULL,
      [Organization_Id] int NULL,
      [Organization_Name] nvarchar(max) NULL,
      [StartDate] datetimeoffset NOT NULL,
      [EndDate] datetimeoffset NOT NULL,
      [ProvisionType] int NOT NULL,
      CONSTRAINT [PK_BillingStatement] PRIMARY KEY ([Id])
  );

现在的问题是我无法将 API 数据保存到数据库中。这是我用于计费语句的主要类,它通过 Crayon NuGet 包获取 API 数据,我希望它存储到 SQL 服务器中。

private static void BillingStatement()
{
var billingStatements = ApiClient.BillingStatements.Get(GetToken(), new BillingStatementFilter { OrganizationId = organization.Id }).GetData().Items;
using (var db = new CrayonDbContext())
            {
                db.BillingStatements.AddRange(billingStatements);
                db.SaveChanges();
            }
}

var billingStatements 正确携带数据,我可以通过调试模式看到。数据也已正确搭建,但是当我运行应用程序并尝试将该 API 数据保存到 Db 时,我收到此错误

“内部异常 1:SqlException:当 IDENTITY_INSERT 设置为 OFF 时,无法在表 'BillingStatements' 中插入标识列的显式值。”

在我目前的情况下,我找不到解决这个问题的方法。我尝试添加“db.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.BillingStatement ON");” 但由于某种原因,Visual Studio 无法识别“ExecuteSqlRaw”,但出现错误。有什么办法可以解决我在代码中遇到的这个问题,以便将数据保存到表中?任何帮助将不胜感激,谢谢。

标签: c#sql-serverentity-frameworkmetadataidentity-insert

解决方案


感谢史蒂夫福特在评论中提供答案。

事实证明我可以添加一个模型构建器解决方案。我在我的 DbContext 上实现了这个:

modelBuilder.Entity().Property(b => b.Id).ValueGeneratedNever();

它有效,谢谢。对于其他有类似问题的人,请尝试该解决方案。


推荐阅读