Невозможно получить элемент из SQLite.Net Async PCL
Я пытаюсь получить элемент по идентификатору, используя асинхронный API SQLite.Net Async PCL. Вот мой модельный класс
public class Invoice : IEntityBase
{
public Invoice()
{
LineItems = new List<LineItem>();
DateCreated = DateTime.Now;
}
[PrimaryKey, AutoIncrement, Column("_id")]
public int Id { get; set; }
public DateTime DateCreated { get; set; }
public int Term { get; set; }
public bool Paid { get; set; }
public decimal Total { get; set; }
public string Notes { get; set; }
[OneToMany(CascadeOperations = CascadeOperation.All)]
public List<LineItem> LineItems { get; set; }
}
И LineItems, который имеет отношение один ко многим здесь
[PrimaryKey, AutoIncrement, Column("_id")]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
public int Qty { get; set; }
[ForeignKey(typeof(Invoice))]
public int InvoiceId { get; set; }
[ManyToOne]
public Invoice Invoice { get; set; }
Вот конструктор:
public SQLiteAsyncConnection DbConnection;
public InvoiceDatabase(ISQLitePlatform platform, string databasePath)
{
if (DbConnection == null)
{
var connectionAsync = new Func<SQLiteConnectionWithLock>(() =>
new SQLiteConnectionWithLock
(
platform,
new SQLiteConnectionString(databasePath, false)
)
);
DbConnection = new SQLiteAsyncConnection(connectionAsync);
DbConnection.CreateTableAsync<Invoice>();
DbConnection.CreateTableAsync<LineItem>();
}
}
Другие методы CRUD (Insert, GetALL) работают, кроме получения Invoice по ID, и Visual Studio, и Xamarin Studio не дают мне никакой полезной трассировки стека.
Вот метод получения
private readonly InvoiceDatabase _database;
public InvoiceRepository(ISQLitePlatform platform, string databasePath)
{
if (_database == null)
{
_database = new InvoiceDatabase(platform, databasePath);
}
}
public async Task<Invoice> GetInvoice(int id)
{
var result = await _database.DbConnection.Table<Invoice>()
.Where(t => t.Id == id)
.FirstOrDefaultAsync();
return result;
}
Я передаю реализацию SQLite для Android, и, как я уже сказал, база данных создана, но я не могу вернуть объект Invoice, я даже пытался
public Task<Invoice> GetInvoiceWithChildren(int id)
{
return _database.DbConnection.GetWithChildrenAsync<Invoice>(id);
}
Любая помощь будет оценена.
1 ответ
После трех дней погони за тенями выяснилось, что это очень простая вещь, которая сбивает меня с толку. Я пытаюсь сохранить список объектов, например, так
[OneToMany(CascadeOperations = CascadeOperation.All)]
public List<LineItem> LineItems { get; set; }
Я пропустил ту часть документации, которая повторяет тот факт, что SQLite.Net является легковесным ORM - этот момент не может быть подчеркнут достаточно, поэтому вам придется удалить ваши полноразмерные шляпы ORM, такие как EF. Таким образом, после прочтения из документации расширения SQLite-Net, которая говорит
Свойства BLOB-объектов текста Свойства BLOB-объектов текста сериализуются в свойство текста при сохранении и десериализируются при загрузке. Это позволяет хранить простые объекты в одной таблице в одном столбце. Свойства текстовых объектов имеют небольшие издержки на сериализацию и десериализацию объектов и некоторые ограничения, но являются лучшим способом хранения простых объектов, таких как List или Dictionary основных типов или простых отношений.
Я меняю свой пропетир так, и теперь все работает как положено. Перейдем к рассмотрению нюансов Async и Await
[TextBlob("LineItemBlobbed")]
public List<LineItem> LineItems { get; set; }
public string LineItemBlobbed { get; set; }