mardi 6 juillet 2021

How to save an object and its children in a generic way?

I have a DataObject class:

public class DataObject {
    public long Id { get; set; }
}

I have two classes that inherit from it (this is an example, there are more on my project):

public class Person : DataObject {
    public long Name { get; set; }
    public IEnumerable<Phone> Phones { get; set; }
}

public class Phone : DataObject {
    public long IdPerson { get; set; } //always in the Id[ParentClassName] format
    public string SerialNumber { get; set; }
}

I want to be able to save parent and children objects in a generic way. These children are always IEnumerable of objects that also inherit from DataObject. For that, i use this generic class:

public class BaseService<T> where T : DataObject {

    private IDbConnection connection;

    public virtual long Save(T obj) {
        using IDbConnection conn = this.connection;
        if (obj.Id == 0) {
            obj.Id = conn.Insert<T>(obj);
        }
        else {
            conn.Update<T>(obj);
        }

        //save the children
        PropertyInfo[] properties = obj.GetType().GetProperties();
        foreach (var property in properties) {
            if (property.PropertyType == typeof(IEnumerable<>)) {
                object? childList = property.GetValue(obj);
                Type[] args = childList.GetType().GetGenericArguments();
                Type childType = args[0];
                foreach (childType childItem in (IEnumerable<childType>)childList) {
                    childItem.GetType().GetProperty($"id{typeof(T).Name}").SetValue(childItem, obj.Id);

                    if (childItem.Id == 0) {
                        childItem.Id = conn.Insert<childType>(childItem);
                    }
                    else {
                        conn.Update<childType>(childItem);
                    }
                }
            }
        }

        return obj.Id;
    }
}

I use this BaseService like this:

BaseService<Person> personService = new BaseService<Person> ();
Person person = new Person();
//fill data here, including the "Phones" property
personService.Save(person);

Problem: I need to get the type of the children properties so i can properly set their parent connection field and save them on the database. I've been reading and trying stuff (the code bellow the comment, in the Save method) but i can't find a way to do it (.net doesn't like my childType variable, says it's a variable used as a type, which is true).

How do I do it?





Aucun commentaire:

Enregistrer un commentaire