/// <summary>
        /// Inserts obejcts without reading them into the cache
        /// only used for manytomany table entries
        /// </summary>
        /// <param name="stmt"></param>
        /// <typeparam name="T"></typeparam>
        public void InsertStatement <T>(InsertExpression <T> stmt)
        {
            var conn = _connection;

            if (conn.State != ConnectionState.Open)
            {
                conn.Open();
            }
            using var cmd   = conn.CreateCommand();
            cmd.CommandText = stmt.AsSqlString();
            cmd.Transaction = _transaction;

            foreach (var(type, id, value) in stmt.GetParameters())
            {
                var param = cmd.CreateParameter();
                param.Value         = value ?? DBNull.Value;
                param.DbType        = type;
                param.ParameterName = id;
                cmd.Parameters.Add(param);
            }
            using var result = cmd.ExecuteReader();
        }
        /// <summary>
        /// Executes the given InsertStatement and maps returned values back into entities
        /// objects created like this are add into the cache as managed entities
        /// </summary>
        /// <param name="stmt"></param>
        /// <typeparam name="TEntity"></typeparam>
        /// <exception cref="Exception"></exception>
        public void Insert <TEntity>(InsertExpression <TEntity> stmt)
        {
            var conn = _connection;

            if (conn.State != ConnectionState.Open)
            {
                conn.Open();
            }
            using var cmd   = conn.CreateCommand();
            cmd.CommandText = stmt.AsSqlString();
            cmd.Transaction = _transaction;
            // set all prepared stmt placeholders
            foreach (var(type, id, value) in stmt.GetParameters())
            {
                var param = cmd.CreateParameter();
                param.Value         = value ?? DBNull.Value;
                param.DbType        = type;
                param.ParameterName = id;
                cmd.Parameters.Add(param);
            }

            using var reader = new CachedDataReader(
                      _ctx.Cache,
                      stmt.Entity,
                      cmd.ExecuteReader(),
                      _ctx
                      );
            //reader reads objects into Cache
            var entries = reader
                          .ReadAllInto(stmt.InsertedObjects.Cast <object>())
                          .ToList();

            //register lazyloaders on newly created objects
            foreach (var cacheEntry in entries)
            {
                RegisterLazyLoader(cacheEntry.Object, cacheEntry.Entity, cacheEntry);
            }
        }