Получить объект со всеми дочерними элементами (и дочерними элементами)
Я хочу получить object
, который сам по себе имеет некоторые свойства, которые имеют тип object
, Эти дочерние объекты снова содержат некоторые object
как свойства.
Если я пытаюсь извлечь данные из базы данных, я получаю результат с детьми на первом уровне, но данные с последовательных уровней null
, В приведенном ниже примере Window
является null
, Из других свойств я получаю данные обратно, как и ожидалось. Если я загляну в базу данных, отношения, кажется, правильные. Только чтение из данных является ошибочным.
отношения
Автомобиль
public class Car
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Model { get; set; }
public string Color { get; set; }
[ForeignKey(typeof(Door))]
public int DoorId { get; set; }
[OneToOne]
public Door Door { get; set; }
}
Дверь
public class Door
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Side { get; set; }
[ForeignKey(typeof(Window))]
public int WindowId { get; set; }
[OneToOne]
public Window Window { get; set; }
}
Окно
public class Window
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public bool Automatic { get; set; }
}
пример
public MainPage()
{
InitializeComponent();
Window window = new Window();
window.Automatic = true;
Door door = new Door();
door.Side = "left";
door.Window = window;
Car car = new Car();
car.Color = "red";
car.Model = "MX5";
car.Door = door;
this.car = car;
}
protected override async void OnAppearing()
{
base.OnAppearing();
await App.Database.StoreCarAsync(this.car);
Car existingCar = await App.Database.GetCarAsync(this.car.Id);
System.Diagnostics.Debug.WriteLine("finished");
}
База данных
public class Database
{
private readonly SQLiteAsyncConnection database;
public Database(string databasePath)
{
this.database = new SQLiteAsyncConnection(databasePath);
this.database.CreateTableAsync<Car>().Wait();
this.database.CreateTableAsync<Door>().Wait();
this.database.CreateTableAsync<Window>().Wait();
}
public async Task<Car> GetCarAsync(int carId)
{
var queryResult = await this.database.Table<Car>().Where(c => c.Id == carId).CountAsync();
if (queryResult > 0)
{
return await this.database.GetWithChildrenAsync<Car>(carId);
}
else
{
return null;
}
}
public async Task<Door> GetDoorAsync(int doorId)
{
var queryResult = await this.database.Table<Door>().Where(d => d.Id == doorId).CountAsync();
if (queryResult > 0)
{
return await this.database.GetWithChildrenAsync<Door>(doorId);
}
else
{
return null;
}
}
public async Task<Window> GetWindowAsync(int windowId)
{
var queryResult = await this.database.Table<Window>().Where(w => w.Id == windowId).CountAsync();
if (queryResult > 0)
{
return await this.database.GetWithChildrenAsync<Window>(windowId);
}
else
{
return null;
}
}
public async Task StoreCarAsync(Car car)
{
await this.StoreDoorAsync(car.Door);
var foundItem = await this.GetCarAsync(car.Id);
if (foundItem != null)
{
await this.database.UpdateWithChildrenAsync(car);
}
else
{
await this.database.InsertWithChildrenAsync(car);
}
}
public async Task StoreDoorAsync(Door door)
{
await this.StoreWindowAsync(door.Window);
var foundItem = await this.GetDoorAsync(door.Id);
if (foundItem != null)
{
await this.database.UpdateWithChildrenAsync(door);
}
else
{
await this.database.InsertWithChildrenAsync(door);
}
}
public async Task<int> StoreWindowAsync(Window window)
{
var foundItem = await this.GetWindowAsync(window.Id);
if (foundItem != null)
{
return await this.database.UpdateAsync(window);
}
else
{
return await this.database.InsertAsync(window);
}
}
}
Разве это не возможно или что я здесь делаю не так?
PS: я использую последние SQLiteNetExtensions.Async v2.0.0-alpha2
Пакет NuGet.
1 ответ
Вы должны использовать каскадное чтение, чтобы прочитать полную иерархию отношений. Сначала отметьте ваши отношения сущностей, чтобы разрешить каскадное чтение, например:
public class Car
{
//snip
[OneToOne(CascadeOperations = CascadeOperation.CascadeRead)]
public Door Door { get; set; }
}
Затем, когда вы читаете из базы данных, установите recursive
параметр к истине. Например:
return await this.database.GetWithChildrenAsync<Door>(doorId, recursive: true);