I'm using ABP framework which is built on top of asp.net core and using entity framework core. I have tried to create PK to a different column other than the default Id column with the help of this solution. Its working fine for every scenario, but my test cases are failing. I have created TestId as PK, Id as autoincrement identity.
It's failing when I'm running test case to create the record and giving the following exception.
SQLite Error 19: 'NOT NULL constraint failed: Test.Id'.
Testcase:
```C#
public async Task Should_Create_Test_With_Valid_Arguments()
{
var Test = await CreateNewTest(K_TESTCode1);
Test.Code = await _TestAppService.CreateTest(Test);
UsingDbContext((System.Action<EntityFrameworkCore.MyProjectDbContext>)(context =>
{
context.Test.FirstOrDefault(
u => u.Code == Test.Code
).ShouldNotBeNull();
}));
}
**CreateNewTest Method**
```C#
public async Task<TestDetailsDto> CreateNewTest(string Code)
{
return CreateTestEntity(Code);
}
public TestDetailsDto CreateTestEntity(string Code)
{
var Test = new TestDetailsDto
{
Code = Code,
};
return Test;
}
CreateTest Method
```C#
public async Task
{
try
{
int TestId = await InsertAndGetIdAsync(ObjectMapper.Map
return input.Code;
}
catch (Exception ex)
{
throw new UserFriendlyException(ex.Message);
}
}
**StackTrace**
> Starting: MyCompany.MyProject.Tests
> [3/6/2018 5:49:05 AM Error] [xUnit.net 00:00:26.6288060] MyCompany.MyProject.Tests.Classifications.TestAppService_Test.Should_Create_Classification_With_Valid_Arguments [FAIL]
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6308959] Microsoft.EntityFrameworkCore.DbUpdateException : An error occurred while updating the entries. See the inner exception for details.
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6309648] ---- Microsoft.Data.Sqlite.SqliteException : SQLite Error 19: 'NOT NULL constraint failed: Test.Id'.
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6323228] Stack Trace:
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6335736] at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.<ExecuteAsync>d__32.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6336454] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6336945] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6337390] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6337813] at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.<ExecuteAsync>d__10.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6338186] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6338566] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6338982] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6339344] at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6339755] at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<SaveChangesAsync>d__61.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6340070] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6340441] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6340850] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6341236] at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6341641] at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<SaveChangesAsync>d__59.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6341947] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6342311] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6342694] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6343065] at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6343431] at Microsoft.EntityFrameworkCore.DbContext.<SaveChangesAsync>d__48.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6343752] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6344115] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6344511] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6345061] D:\Github\aspnetboilerplate\src\Abp.EntityFrameworkCore\EntityFrameworkCore\AbpDbContext.cs(215,0): at Abp.EntityFrameworkCore.AbpDbContext.<SaveChangesAsync>d__49.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6348796] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6349402] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6349858] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6350373] D:\Github\aspnetboilerplate\src\Abp.EntityFrameworkCore\EntityFrameworkCore\Uow\EfCoreUnitOfWork.cs(163,0): at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.<SaveChangesInDbContextAsync>d__20.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6350804] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6351201] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6351665] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6352134] D:\Github\aspnetboilerplate\src\Abp.EntityFrameworkCore\EntityFrameworkCore\Uow\EfCoreUnitOfWork.cs(68,0): at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.<SaveChangesAsync>d__12.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6352535] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6352935] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6353330] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6353808] D:\Github\aspnetboilerplate\src\Abp.EntityFrameworkCore\EntityFrameworkCore\Uow\EfCoreUnitOfWork.cs(83,0): at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.<CompleteUowAsync>d__14.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6354207] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6354685] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6355115] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6355558] D:\Github\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkBase.cs(276,0): at Abp.Domain.Uow.UnitOfWorkBase.<CompleteAsync>d__57.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6355921] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6356306] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6356695] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6357135] D:\Github\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs(90,0): at Abp.Domain.Uow.UnitOfWorkInterceptor.<>c__DisplayClass6_0.<<PerformAsyncUow>b__0>d.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6357587] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6359838] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6360322] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6360807] D:\Github\aspnetboilerplate\src\Abp\Threading\InternalAsyncHelper.cs(40,0): at Abp.Threading.InternalAsyncHelper.<AwaitTaskWithPostActionAndFinally>d__1.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6361199] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6361583] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6362001] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6362425] D:\Github\aspnetboilerplate\src\Abp\Threading\InternalAsyncHelper.cs(20,0): at Abp.Threading.InternalAsyncHelper.<AwaitTaskWithFinally>d__0.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6362869] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6363327] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6363782] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6364332] C:\Users\pooja.dhadse\Source\MyProject\aspnet-core\test\MyCompany.MyProject.Tests\Classifications\TestAppService_Test.cs(20,0): at MyCompany.MyProject.Tests.Classifications.TestAppService_Test.<Should_Create_Classification_With_Valid_Arguments>d__1.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6364752] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6365185] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6365609] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6365946] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6366305] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6366710] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6367020] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6367403] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6367790] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6368122] ----- Inner Stack Trace -----
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6368492] at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6368883] at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6369347] at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6369741] at Microsoft.Data.Sqlite.SqliteCommand.<ExecuteDbDataReaderAsync>d__52.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6370066] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6370420] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6370829] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6371183] at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6371579] at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.<ExecuteAsync>d__17.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6371886] --- End of stack trace from previous location where exception was thrown ---
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6372250] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6372632] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6372995] at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6373387] at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.<ExecuteAsync>d__32.MoveNext()
> [3/6/2018 5:49:06 AM Informational] [xUnit.net 00:00:26.6922065] Finished: MyCompany.MyProject.Tests
> [3/6/2018 5:49:06 AM Informational] ========== Run test finished: 1 run (0:00:28.3709989) ==========
**Code:**
```C#
public class Test: FullAuditedEntity
{
// PK
[MaxLength(NVarcharLength14), DataType(DataType.Text)]
public virtual string Code { get; set; }
// Unique constraint
public int MyUniqueId { get; set; }
}
public class AbpProjectNameDbContext : AbpZeroDbContext<Tenant, Role, User, AbpProjectNameDbContext>
{
/* Define a DbSet for each entity of the application */
public DbSet<Test> Tests { get; set; }
public AbpProjectNameDbContext(DbContextOptions<AbpProjectNameDbContext> options) : base(options) {}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Test>().Property(t => t.Id).ValueGeneratedOnAdd(); // Auto-increment
modelBuilder.Entity<Test>().HasAlternateKey(t => t.Id); // Auto-increment, closed-wont-fix: https://github.com/aspnet/EntityFrameworkCore/issues/7380
modelBuilder.Entity<Test>().HasKey(t => t.Code); // PK
modelBuilder.Entity<Test>().HasIndex(t => t.MyUniqueId).IsUnique(); // Unique constraint
}
}
Generated migration:
```C#
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Tests",
columns: table => new
{
Code = table.Column
Id = table.Column
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
MyUniqueId = table.Column
},
constraints: table =>
{
table.PrimaryKey("PK_Tests", x => x.Code);
});
migrationBuilder.CreateIndex(
name: "IX_Tests_MyUniqueId",
table: "Tests",
column: "MyUniqueId",
unique: true);
}
**Usage:**
```C#
public async Task MyMethod()
{
await _repository.InsertAndGetIdAsync(new Test
{
Code = "One",
MyUniqueId = 1
});
// Valid
await _repository.InsertAndGetIdAsync(new Test
{
Code = "Two",
MyUniqueId = 2
});
try
{
await _repository.InsertAndGetIdAsync(new Test
{
Code = "One", // PK conflict
MyUniqueId = 3
});
}
catch (Exception e)
{
}
try
{
await _repository.InsertAndGetIdAsync(new Test
{
Code = "Three",
MyUniqueId = 1 // Unique constraint conflict
});
}
catch (Exception e)
{
throw;
}
return null;
}
EF Core version: 2.0.1
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Windows 10
IDE: Visual Studio 2017 15.4
@viveknuna Looks like the migration was generated against SQL Server, but is being used with SQLite. Does it work correctly if the migration is instead created for use with SQLite?
Yes, migration is generated against sql server. I don鈥檛 run any migrations explicitly for my test cases, But test cases use SQLite. SQLite generates same schema.
So is this SQLite related issue or there is some problem with my current implementation?
Please let me know what should I try at my end?
My application uses sql server only, but test cases use SQLite. I鈥檓 using XUnit.
@viveknuna Migrations are generated against the provider that you are using and may contain code specific to that provider. If you want to test against a different provider, then consider either:
@ajcvickers EnsureDeleted+EnsureCreatd is not working for me.
Entity Framework Core .NET Command-line Tools 2.2.4-servicing-10062
EF Core 2.2.4
Microsoft.EntityFrameworkCore.Database.Command:Error: Failed executing DbCommand (14ms)
[Parameters=[@p0='1' (DbType = String), @p1='1' (DbType = String), @p2='2019-06-20T15:08:52.8230073+00:00' (DbType = String)], CommandType='Text', CommandTimeout='30']
INSERT INTO "DevicesOrderStatus" ("OrderId", "Status", "UtcSetAt")
VALUES (@p0, @p1, @p2);
SELECT "Id"
FROM "DevicesOrderStatus"
WHERE changes() = 1 AND "OrderId" = @p0 AND "Id" = last_insert_rowid();
So I assume Id should have AUTOINCREMENT for SQLite because it is configured as b.Property<int>("Id").ValueGeneratedOnAdd() .
However, SQLite shows this SQL for the table:
CREATE TABLE "DevicesOrderStatus" (
"OrderId" INTEGER NOT NULL,
"Id" INTEGER NOT NULL,
"Status" INTEGER NOT NULL,
"UtcSetAt" TEXT NOT NULL,
CONSTRAINT "PK_DevicesOrderStatus" PRIMARY KEY ("OrderId", "Id"),
CONSTRAINT "FK_DevicesOrderStatus_DevicesOrder_OrderId" FOREIGN KEY ("OrderId") REFERENCES "DevicesOrder" ("Id") ON DELETE CASCADE,
CONSTRAINT "FK_DevicesOrderStatus_DevicesOrderStatusType_Status" FOREIGN KEY ("Status") REFERENCES "DevicesOrderStatusType" ("Id") ON DELETE RESTRICT
)
I see nothing which indicates automatic increment of Id column.
DevicesOrderStatus is configured as an owned entity of an order:
internal sealed class DevicesOrderConfiguration : IEntityTypeConfiguration<DevicesOrder>
{
public void Configure(EntityTypeBuilder<DevicesOrder> builder)
{
builder.ToTable("DevicesOrder");
builder.Property(_ => _.Version)
.HasDefaultValue(0)
.IsConcurrencyToken();
builder.Ignore(_ => _.OrderItemsCount);
builder.Ignore(_ => _.CurrentStatus);
builder.HasKey(_ => _.Id);
builder.OwnsMany(_ => _.OrderItems, b =>
{
b.ToTable("DevicesOrderItem");
b.HasForeignKey("OrderId");
b.HasKey("OrderId", nameof(DevicesOrderItem.ModelId));
b.HasOne<DeviceModel>()
.WithMany()
.HasForeignKey(m => m.ModelId)
.IsRequired()
.OnDelete(DeleteBehavior.Restrict);
});
builder.OwnsMany(_ => _.StatusHistory, b =>
{
b.ToTable("DevicesOrderStatus");
b.HasForeignKey("OrderId");
b.Property<int>("Id").ValueGeneratedOnAdd();
b.HasKey("OrderId", "Id");
b.HasOne<DevicesOrderStatusLookup>()
.WithMany()
.HasForeignKey(m => m.Status)
.IsRequired()
.OnDelete(DeleteBehavior.Restrict);
});
builder.HasOne<Organization>()
.WithMany()
.HasForeignKey(_ => _.OrganizationId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
}
}
@voroninp See #15497. SQLite doesn't support auto-increment on composite keys.
@ajcvickers I am spoiled by SQL Server =)
But is it hard for EF Core to detect this situation? Can EF signal that configuration in the context of particular provider is not correct?
Re-opening to discuss @voroninp's suggestion.
Note from triage: putting this on the backlog to add TODO comments in the generated migration indicating that EF was not able to implement any store-generation in the implemented migration. Note, however, that if client side generation is being used, then it's fine for the column to not be store-generated.
Hello, It seems we're hitting a similar issue when using owned entity types with a composite key including an int property with a value of 0.
```c#
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
namespace ConsoleApp1
{
internal class Program
{
private static void Main()
{
var options = new DbContextOptionsBuilder
.UseSqlite("datasource=db.sqlite")
.Options;
using var ctx = new MyContext(options);
ctx.Database.EnsureCreated();
ctx.Add(new Input { Boosters = { new Booster { Index = 0 } } }); // no exception when the index > 0
ctx.SaveChanges();
}
}
public class MyContext : DbContext
{
public MyContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity().OwnsMany(i => i.Boosters, b =>
{
b.HasKey("InputId", "Index");
});
}
}
public class Input
{
public int InputId { get; set; }
public ICollection
}
public class Booster
{
public int Index { get; set; }
}
}
## Exception
```c#
Microsoft.EntityFrameworkCore.DbUpdateException
HResult=0x80131500
Message=An error occurred while updating the entries. See the inner exception for details.
Source=Microsoft.EntityFrameworkCore.Relational
StackTrace:
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(DbContext _, ValueTuple`2 parameters)
at Microsoft.EntityFrameworkCore.Storage.Internal.NoopExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IList`1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
at ConsoleApp1.Program.Main() in C:\deleteme\ef\ConsoleApp1\Program.cs:line 17
This exception was originally thrown at this call stack:
Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(int, SQLitePCL.sqlite3)
Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(System.Data.CommandBehavior)
Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReader(System.Data.CommandBehavior)
System.Data.Common.DbCommand.ExecuteReader()
Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(Microsoft.EntityFrameworkCore.Storage.RelationalCommandParameterObject)
Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(Microsoft.EntityFrameworkCore.Storage.IRelationalConnection)
Inner Exception 1:
SqliteException: SQLite Error 19: 'NOT NULL constraint failed: Booster.Index'.
EF Core version: 3.0.1 (also tried 3.1.0-preview3.19554.8)
Database Provider: Microsoft.EntityFrameworkCore.Sqlite
Project: netcoreapp3.1 console app
It looks like configuring the int property with ValueGeneratedNever can be a workaround.
c#
modelBuilder.Entity<Input>().OwnsMany(i => i.Boosters, b =>
{
b.HasKey("InputId", "Index");
b.Property(b => b.Index).ValueGeneratedNever();
});
@gojanpaolo Thank you very much, It's worked for me.
Ive run into this issue. I am trying to initialize a SQLDatabase and seed it.
SQLite Error 19: 'NOT NULL constraint failed: Freights.UpdatedOn'.
Inspecting my entity I see the UpdatedOn field is set.
Inspecting my db, I see the table created correctly.
I am using a custom OnConfiguring
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite("Data Source=my.db");
and custom IDesignTimeDbContextFactory with SQLITE
IDesignTimeDbContextFactory
Most helpful comment
Hello, It seems we're hitting a similar issue when using owned entity types with a composite key including an
intproperty with a value of0.```c#
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
namespace ConsoleApp1() Boosters { get; } = new List();
{
internal class Program
{
private static void Main()
{
var options = new DbContextOptionsBuilder
.UseSqlite("datasource=db.sqlite")
.Options;
using var ctx = new MyContext(options);
ctx.Database.EnsureCreated();
ctx.Add(new Input { Boosters = { new Booster { Index = 0 } } }); // no exception when the index > 0
ctx.SaveChanges();
}
}
public class MyContext : DbContext
{
public MyContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity().OwnsMany(i => i.Boosters, b =>
{
b.HasKey("InputId", "Index");
});
}
}
public class Input
{
public int InputId { get; set; }
public ICollection
}
public class Booster
{
public int Index { get; set; }
}
}
Further technical details
EF Core version: 3.0.1 (also tried 3.1.0-preview3.19554.8)
Database Provider: Microsoft.EntityFrameworkCore.Sqlite
Project: netcoreapp3.1 console app
Workaround
It looks like configuring the
intproperty withValueGeneratedNevercan be a workaround.c# modelBuilder.Entity<Input>().OwnsMany(i => i.Boosters, b => { b.HasKey("InputId", "Index"); b.Property(b => b.Index).ValueGeneratedNever(); });