Не удается сохранить данные в БД, так как вставка удостоверений отключена

Я рассмотрел несколько вопросов с этой проблемой, но многие из них можно решить с помощью быстрой аннотации класса, но я использую метаданные для своих файлов классов, поэтому мне приходится использовать ModelBuilder для настройки отношений в моей базе данных из классов. Я уже знаю, в чем проблема, в мою таблицу нельзя вставить данные идентификатора, но я не уверен, как это изменить в текущем сценарии, поскольку я использую метаданные. Я рассмотрю свой код ниже, чтобы показать вам, почему это отличается.

Вот мой код.

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);
            }
        }

Вот класс BillingStatement из метаданных, которые он использует из пакета CrayonApi NuGet здесь.

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 в БД. Это мой основной класс для выставления счетов, который принимает данные API через пакет Crayon NuGet, и я хочу, чтобы они сохранялись на сервере 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 в БД, я получаю эту ошибку

Внутреннее исключение 1: SqlException: невозможно вставить явное значение для столбца идентификаторов в таблицу «BillingStatements», если для параметра IDENTITY_INSERT установлено значение OFF.

Я не могу найти способ исправить это в моем текущем экземпляре. Я попытался добавить db.Database.ExecuteSqlRaw(SET IDENTITY_INSERT dbo.BillingStatement ON); но я получаю сообщение об ошибке с ExecuteSqlRaw по какой-то причине Visual Studio не распознает его. Можно ли как-то исправить эту проблему в моем коде, чтобы я мог сохранить данные в таблицу? Любая помощь будет оценена по достоинству, спасибо.


person KyleAT    schedule 20.01.2021    source источник
comment
Вы можете использовать .ValueGeneratedOnAdd() в вашем modelBuilder — см. docs.microsoft.com/en-us/ef/core/modeling/   -  person Steve Ford    schedule 20.01.2021
comment
@SteveFord Lol, после написания такой большой проблемы это было действительно так просто, большое спасибо, Стив, я ценю это.   -  person KyleAT    schedule 20.01.2021


Ответы (1)


Спасибо Стиву Форду в комментариях за ответ.

Оказывается, я могу добавить решение ModelBuilder. Я реализовал это в своем DbContext:

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

И это работает, спасибо. Всем, у кого есть похожая проблема, попробуйте это решение.

person KyleAT    schedule 20.01.2021