C# 一个its组合键的SqLite自动增量

C# 一个its组合键的SqLite自动增量,c#,.net,entity-framework,sqlite,testing,C#,.net,Entity Framework,Sqlite,Testing,以下列在SQL Server IDENTITY1,1中设置为自动递增,我希望在SqLite上有类似的行为:Tenant.TenantID、Project.ProjectID和Credits.CreditsID。虽然SqLite中有AUTOINCREMENT,我也尝试过,但它只适用于只有一个主键的表。我尝试了以下测试: 顺便说一下,我使用了Microsoft.EntityFrameworkCore.Sqlite 2.1.4进行此测试 将这些列的值显式指定为“自动递增”: 租户 a-99:保存后保留

以下列在SQL Server IDENTITY1,1中设置为自动递增,我希望在SqLite上有类似的行为:Tenant.TenantID、Project.ProjectID和Credits.CreditsID。虽然SqLite中有AUTOINCREMENT,我也尝试过,但它只适用于只有一个主键的表。我尝试了以下测试:

顺便说一下,我使用了Microsoft.EntityFrameworkCore.Sqlite 2.1.4进行此测试

将这些列的值显式指定为“自动递增”:

租户

a-99:保存后保留-99

b。0:保存后变为1

c。99:保存后仍为99

对于Project.projectd和Credits.CreditsID

a-保存对DbContext的更改后,99&99值保持不变。但是我不想显式地分配这些值,因为有来自DbContext的大量测试数据

b。分配显式值0会引发以下错误:Microsoft.Data.Sqlite.SqliteException:Sqlite错误19:“非空约束失败:Credits.CreditsID”


我真的很感激有人能帮我解决这个问题。这已经困扰了我好几天了。

对于SQLite,您可能不想使用AUTOINCREMENT,这实际上并没有将列设置为increment,而是设置了一个约束,即如果不显式设置值,则该值必须比已分配的值高

如果不显式设置值,只需使用INTEGER主键定义列,即可将列设置为增量。注意,每个表只能有一个这样的列

请注意,SQLite不保证递增1,而是保证一个唯一标识符,该标识符是一个整数,只有在分配了和id 9223372036854775807之后,该标识符可能更小。。在这种情况下,使用AUTOINCREMENT将失败,并出现SQLIte完全异常,而如果没有AUTOINCREMENT,SQLIte将尝试查找未使用的id。 查看您的图表,我相信积分表不需要Tennanti,因为这可以通过引用Tennant的项目获得

忽略构成关系的列之外的其他列,同时添加可选的外键约束,以强制引用完整性,那么我相信您可以使用以下内容:-

DROP TABLE IF EXISTS credits;
DROP TABLE IF EXISTS project;
DROP TABLE IF EXISTS tennant;
CREATE TABLE IF NOT EXISTS tennant (tennant_id INTEGER PRIMARY KEY, Name TEXT, other_columns);
CREATE TABLE IF NOT EXISTS project (project_id INTEGER PRIMARY KEY, tennant_reference REFERENCES tennant(tennant_id), Title);
CREATE TABLE IF NOT EXISTS credits (credit_id INTEGER PRIMARY KEY, project_reference INTEGER REFERENCES project(project_id), other_columns TEXT);
CREATE TABLE IF NOT EXISTS creidts (credit_id INTEGER PRIMARY KEY, project_reference INTEGER, other_columns);
INSERT INTO tennant VALUES(1,'Fred','other data'); -- Explicit ID 1
INSERT INTO tennant (Name,other_columns) VALUES('Mary','Mary''s other data'),('Anne','Anne''s other data'); -- Implicit ID 's (2 and 3 most likely)
INSERT INTO project VALUES (99,1,'Project001 for Fred'); --  Explicit Project ID 99 - tennant 1 = Fred
INSERT INTO project (tennant_reference,Title) VALUES(1,'Project002 for Fred'),(2,'Project003 for Mary'),(3,'Project004 for Anne'); -- 3 implicit project id's 100,101 and 102 (most likely)

-- Result 1
SELECT * FROM project JOIN tennant ON tennant_reference = tennant.tennant_id;

INSERT INTO credits VALUES(199,99,'Other credit columns'); -- Explicit credit ID of 199 for Project001 (tennant implied) 
INSERT INTO credits VALUES(0,99,'Other credit colums credit_id = 0'); -- Explicit credit ID of 0 for Project002
INSERT INTO credits (project_reference,other_columns) VALUES (100,'for Project002'),(100,'another for Project002'),(102,'for Project004');

SELECT * FROM credits JOIN project ON project_reference = project_id JOIN tennant ON tennant_reference = tennant_id;
这将删除所有现有表,以简化测试。 然后创建这3个表。 行以建议的方式显式和隐式插入到Tennant表中,然后插入到项目表中请注意,由于外键约束,无法将引用不存在的Tennant的行插入到项目表中 然后列出项目以及连接的tennant详细信息,请参见结果 然后使用显式和隐式credit id将行插入Credits表。注意,199是显式定义的,然后是0。 正如您所看到的,当自动生成id时,它们通常比迄今为止使用的最大值大1。 后果 与Tennant相关的第一个查询项目 第二次查询相关项目和底层相关Tennant的信用
旁注:我不会让TenantID成为项目主键的一部分,也不会让ProjectID和TenantID成为Credit主键的一部分。每个表只有一个PK列,父表只有一个外键,也就是说,信用卡中根本没有租户。如果您必须更改引用,这将使数据管理变得更加容易。虽然我可能同意您的计划,因为这是我通常的数据库设计方式,但对于这个项目,数据库设计师之所以采用这种方式,是因为他计划将此分区。哇!非常感谢你的解释。虽然这很有帮助,但我对设计几乎没有控制权——我会这么说。对于这个项目,db设计者采用这种方式,因为他计划将其分区。