自动递增插入

5

我正在尝试将一些数据插入到我的SQLite数据库中,当我使用一个记录进行操作时,这完全是可行的。但是在循环内部,我会遇到错误。首先,这里是代码:

string dataSource = "Data Source=";
Connection = new SQLiteConnection(dataSource + this.DatabasePath);

var context = new DataContext(Connection);

var users = context.GetTable<User>();


for (int i = 0; i < 2; i++) {
    User tempUser = new User() {
        ID = null,
        EMail = i + "@" + i + ".de",
        Password = "Test1234",
        JoinedDate = DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss")
    };

    users.InsertOnSubmit(tempUser);
    context.SubmitChanges();
}

用户本身
[Table(Name = "User")]
public class User {

    [Column(Name = "UserID", IsPrimaryKey = true, CanBeNull = false)]
    public int? ID { get; set; }

    [Column(Name = "EMail", CanBeNull = false)]
    public string EMail { get; set; }

    [Column(Name = "Password", CanBeNull = false)]
    public string Password { get; set; }

    [Column(Name = "JoinedDate", CanBeNull = false)]
    public String JoinedDate { get; set; }

    [Column(Name = "PaymentMethodID")]
    public int PaymentMethodID { get; set; }
}

表格是这样创建的:
CREATE TABLE "User" (
`UserID`    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`EMail` TEXT NOT NULL,
`Password`  TEXT NOT NULL,
`JoinedDate`    TEXT NOT NULL,
`Licenses`  INTEGER,
`PaymentMethodID`   INTEGER
)

最后我收到的错误信息:

发生了“System.Data.Linq.DuplicateKeyException”类型的异常,但未在用户代码中处理

附加信息:无法添加已使用其键的实体。

我敢打赌,这是因为字段 ID 被设置为 AutoIncrement 导致的。


可能是[使用System.Data.Linq.Mapping和在sqlite数据库中自动递增主键时出现错误]的重复问题(https://dev59.com/243da4cB1Zd3GeqP0XdE) - Salah Akbari
你应该拥有 public int ID { get; set; }(不可为空),并将属性标记为 DatabaseGenerated = Identity - Gert Arnold
2个回答

0

你只需要移除ID = null,因为这是自动递增的,不需要写这个。 在“User”表中删除自动递增列ID的NOT NULL检查,并且在“User”类中也删除。由于ID列是自动递增的,所以不需要使用NOT NULL约束进行检查。

for (int i = 0; i < 2; i++) {
    User tempUser = new User() {
        EMail = i + "@" + i + ".de",
        Password = "Test1234",
        JoinedDate = DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss")
    };

请在 UserID 的定义中移除 NOT NULL 检查:UserID INTEGER PRIMARY KEY AUTOINCREMENT, - Nitin Chotaliya
你需要从表“User”和类“User”中都删除。 - Nitin Chotaliya
请使用以下方式 [Column(Name = "UserID", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert, DbType = "Int NOT NULL IDENTITY")]。 - Nitin Chotaliya
使用@NitinChotaliya的代码,我遇到了错误“System.Data.SQLite.SQLiteException”类型的异常在“System.Data.Linq.dll”中发生,但未在用户代码中处理附加信息:SQL逻辑错误或缺少数据库靠近“SELECT”的位置:语法错误 - DirtyNative
请编辑代码并使用以下方式 [Column(Name = "UserID", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]。 - Nitin Chotaliya
显示剩余2条评论

0

假设您的代码在插入一个项目时已经正常工作,那么我建议您尝试以下解决方案之一:

解决方案1

context.SubmitChanges();调用放在循环之外。

因此:

for (int i = 0; i < 2; i++) {
    User tempUser = new User() {
        ID = null,
        EMail = i + "@" + i + ".de",
        Password = "Test1234",
        JoinedDate = DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss")
    };

    users.InsertOnSubmit(tempUser);

}
context.SubmitChanges();

解决方案2

使用InsertAllOnSubmit

var tempUsers = Enumerable.Range(0, 2)
                      .Select(i => new User{
                                   ID = null,
                                   EMail = i + "@" + i + ".de",
                                   Password = "Test1234",
                                   JoinedDate = DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss")
                      });

users.InsertAllOnSubmit(tempUsers);
context.SubmitChanges();

解决方案3

在每个循环中处理并重新创建上下文(似乎是一个相当不好的想法)

for (int i = 0; i < 2; i++) {
   using (var context = new DataContext(Connection)) {
     var users = context.GetTable<User>();

     User tempUser = new User() {

        ID = null,
        EMail = i + "@" + i + ".de",
        Password = "Test1234",
        JoinedDate = DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss")
    };

     users.InsertOnSubmit(tempUser);
     context.SubmitChanges();
   }
}

只有解决方案3对我有效。但这是一个好的解决方案吗?特别是在考虑速度时。 - DirtyNative
@DanielDirtyNativeMartin 不,不是这样的... 或许还有另一种方法:http://stackoverflow.com/questions/31145955/cannot-insert-multiple-items-into-sqlite-database - Raphaël Althaus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接