简体   繁体   中英

Arrays of multiple (related) class types in SQLite-Net Extensions

Is there a way to have a collection of different class types which inherit from the same parent class in SQLite.Net Extensions? Ideally I would like to have an array of objects which conform to an interface or abstract class, however I can't even get child types of standard classes to work.

public class ActivityCategory
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    public string Title { get; set; }
    public string Icon { get; set; }
    public bool Recommended { get; set; }

    [OneToMany(CascadeOperations = CascadeOperation.All)]
    public SomeAbstractClass[] multipleTypesAllowed { get; set; }
}

public abstract class SomeAbstractClass
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }

    public string SomeValue { get; set; }

    [ForeignKey(typeof(ActivityCategory))]
    public int ActivityCategoryId { get; set; }

    [ManyToOne(CascadeOperations = CascadeOperation.All)]
    public ActivityCategory Category { get; set; }
}

I can't get the above to return anything other than an empty array for the multipleTypesAllowed. It works if I make the parent class not abstract and instantiate it, but even child classes of that don't work. Is there any way to have inheritance work with SQLite.Net?

Cheers.

When you get the ActivityCategory object using GetWithChildren, internally sqlite-net uses a reflection to call new ActivateCategory() and then new SomeAbstractClass() for each one of the children. That's why all generics in sqlite-net library have the constraint where T : new() . This is the reason you got an empty array when your class is abstract. It just can't be instantiated by the library. If you want to store instances of different types inside the same array, you can't make sqlite-net guessing for you which type should it use each time. I don't know the logic of your application, of course, but I think that you can't avoid writing queries manually - without using sqlite-net extensions. If, for example, your base class is Vehicle, and Car & Truck are derived classes, you could use:

    db.CreateTable<Vehicle>();
    Car c = new Car();
    Truck t = new Truck();
    db.Insert(c, typeof(Vehicle));
    db.Insert(t, typeof(Vehicle));
    ...
    List<Car> cars = db.Query<Car>("select * from Vehicle where VehicleType = ?", VehicleTypes.Car);
    List<Truck> trucks = db.Query<Truck>("select * from Vehicle where VehicleType = ?", VehicleTypes.Truck);

Then you could combine two lists into one list of Vehicle and add this list to your parent instance (ActivityCategory in your example).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM