public object GetList(ObjectWithID obj, string propertyName)
        {
            var objType      = obj.GetType();
            var property     = objType.GetProperty(propertyName);
            var propertyType = property.PropertyType;
            var relatedType  = propertyType.GenericTypeArguments[0];

            foreach (var relatedProperty in relatedType.GetProperties())
            {
                var relatedPropertyType = relatedProperty.PropertyType;
                if (objType == relatedPropertyType || objType.IsSubclassOf(relatedPropertyType))
                {
                    var idList = new List <uint>();
                    Command.CommandText = $"SELECT ID FROM {relatedType.Name} WHERE {relatedProperty.Name} = {obj.ID}";
                    using (var reader = Command.ExecuteReader())
                        while (reader.Read())
                        {
                            idList.Add((uint)reader[0]);
                        }
                    var result  = propertyType.GetConstructor(Type.EmptyTypes).Invoke(null);
                    var addFunc = propertyType.GetMethod("Add");
                    foreach (var id in idList)
                    {
                        var data = CreateObject(id, relatedType);
                        addFunc.Invoke(result, new object[] { data });
                    }
                    return(result);
                }
            }
            return(null);
        }
        public void SetValue(ObjectWithID obj, string propertyName, object value)
        {
            var property      = obj.GetType().GetProperty(propertyName);
            var declaringType = property.DeclaringType;
            var propertyType  = property.PropertyType;

            Command.CommandText = $"UPDATE {declaringType.Name} SET {property.Name} = @Value WHERE ID = {obj.ID}";
            Command.Parameters.Clear();
            // ObjectWithID子类
            if (value is ObjectWithID data)
            {
                Command.Parameters.Add("@Value", MySqlDbType.UInt32);
                Command.Parameters["@Value"].Value = data.ID;
            }
            // Nullable<Enum>
            else if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable <>) && propertyType.GenericTypeArguments[0].IsEnum)
            {
                Command.Parameters.Add("@Value", MySqlDbType.Text);
                Command.Parameters["@Value"].Value = value.ToString();
            }
            // 一般类型
            else
            {
                Command.Parameters.Add("@Value", _TypeToDbType[property.PropertyType]);
                Command.Parameters["@Value"].Value = value;
            }
            Command.ExecuteNonQuery();
        }
        public ObjectWithID CreateObject(uint id, Type type)
        {
            var baseType = type;

            while (baseType.BaseType != typeof(ObjectWithID))
            {
                baseType = baseType.BaseType;
            }
            Command.CommandText = $"SELECT Type FROM {baseType.Name} WHERE ID = {id}";
            using (var reader = Command.ExecuteReader())
            {
                reader.Read();
                var guid = new Guid((byte[])reader[0]);
                return(ObjectWithID.GetByID(id, guid));
            }
        }
        public object GetValue(ObjectWithID obj, string propertyName)
        {
            var property      = obj.GetType().GetProperty(propertyName);
            var declaringType = property.DeclaringType;
            var propertyType  = property.PropertyType;

            // ObjectWithID子类
            if (propertyType.IsSubclassOf(typeof(ObjectWithID)))
            {
                uint id;
                Command.CommandText = $"SELECT {propertyName} FROM {declaringType.Name} WHERE ID = {obj.ID}";
                using (var reader = Command.ExecuteReader())
                {
                    reader.Read();
                    id = (uint)reader[0];
                }
                return(CreateObject(id, propertyType));
            }
            // Nullable<Enum>
            if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable <>) && propertyType.GenericTypeArguments[0].IsEnum)
            {
                Command.CommandText = $"SELECT {propertyName} FROM {declaringType.Name} WHERE ID = {obj.ID}";
                using (var reader = Command.ExecuteReader())
                {
                    reader.Read();
                    return(Enum.Parse(propertyType.GenericTypeArguments[0], (string)reader[0]));
                }
            }
            // 一般类型
            Command.CommandText = $"SELECT {propertyName} FROM {declaringType.Name} WHERE ID = {obj.ID}";
            using (var reader = Command.ExecuteReader())
            {
                reader.Read();
                return(reader[0]);
            }
        }