Я пытаюсь вставить некоторые данные в свою базу данных 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' произошло в System.Data.Linq.dll, но не было обработано в пользовательском коде

Дополнительная информация: Eine Entität, deren Schlüssel bereits verwendet wird, kann nicht hinzugefügt werden.

Могу поспорить, что это происходит из-за поля ID, для которого установлено значение AutoIncrement.

5
Daniel DirtyNative Martin 11 Май 2016 в 13:04

2 ответа

Лучший ответ

Предполагая, что ваш код отлично работает с одной вставкой, я бы попробовал одно из этих решений

Решение 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();
   }
}
0
Raphaël Althaus 11 Май 2016 в 12:24

Вы просто удаляете ID = null, потому что это автоинкремент, и писать это не нужно. Измените таблицу «Пользователь», удалите проверку NOT NULL в идентификаторе столбца Автоинкремент, а также удалите в классе «Пользователь». Столбец идентификатора имеет автоматическое приращение, поэтому проверка с ограничением 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")
    };
0
Nitin Chotaliya 11 Май 2016 в 12:12