Я получаю список объектов из веб-сервиса. Данные должны храниться в базе данных SQLite. Таким образом, я могу сохранить первый элемент в базе данных с помощью InsertWithChildrenAsync()
, на втором я получаю исключение, и приложение вылетает.
Определение класса:
public class Color
{
[PrimaryKey]
public string Code { get; set; }
public string Name { get; set; }
}
public class Person
{
[PrimaryKey]
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey(typeof(Color))]
public string FavoriteColorId { get; set; }
[OneToOne(CascadeOperations = CascadeOperation.All)]
public Color FavoriteColor { get; set; }
}
Инициализация:
var dbPath = DependencyService.Get<IStorageService>().GetFilePathForDB();
DependencyService.Get<IStorageService>().DeleteFile(dbPath);
var db = new SQLiteAsyncConnection(dbPath);
await db.CreateTableAsync<Color>();
await db.CreateTableAsync<Person>();
Код, демонстрирующий проблему:
var pers1 = new Person()
{
Id = 1,
Name = "John",
FavoriteColor = new Color() { Code = "FF0000", Name = "Red" }
};
var pers2 = new Person()
{
Id = 2,
Name = "Doe",
FavoriteColor = new Color() { Code = "FF0000", Name = "Red" }
};
await db.InsertWithChildrenAsync(pers1, true);
await db.InsertWithChildrenAsync(pers2, true);
Сообщение об ошибке
SQLite.SQLiteException: ограничение
Этого не произойдет, если я использую
var pers2 = new Person()
{
Id = 2,
Name = "Doe",
FavoriteColor = new Color() { Code = "00FF00", Name = "Green" }
};
Проблема в том, что один и тот же первичный ключ вставляется дважды. Одним из решений было бы использование автоматического увеличения, но тогда одни и те же данные сохраняются несколько раз. Как я могу использовать одни и те же данные для разных объектов? Данные из веб-сервиса анализируются и позже сохраняются в базе данных. Я не держу объекты в памяти все время. В противном случае я мог бы использовать что-то вроде
Color red = new Color { Code = "00FF00", Name = "Green" };
pers1.FavoriteColor = red;
pers2.FavoriteColor = red;
Нужна ли мне таблица «многие ко многим»? Что насчет удаления? В настоящее время я планирую использовать DeleteAsync()
, но запись не может быть полностью удалена, потому что ее использует другой экземпляр. Учитывает ли это метод?
Каковы мои варианты?