Я рассмотрел несколько вопросов с этой проблемой, но многие из них можно решить с помощью быстрой аннотации класса, но я использую метаданные для своих файлов классов, поэтому мне приходится использовать 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 не распознает его. Можно ли как-то исправить эту проблему в моем коде, чтобы я мог сохранить данные в таблицу? Любая помощь будет оценена по достоинству, спасибо.