public async Task Test_EntityMapperPerformanceAsync(int index)
        {
            index++;



            IDatabase database = _sqlite;

            IList <BookEntity_Client>?books = Mocker.GetBooks_Client(500);

            TransactionContext?trans = await _sqlIteTransaction.BeginTransactionAsync <BookEntity_Client>().ConfigureAwait(false);

            IEnumerable <BookEntity_Client> re = await database.RetrieveAsync <BookEntity_Client>(b => b.Deleted, trans).ConfigureAwait(false);

            await database.AddAsync <BookEntity_Client>(Mocker.GetBooks_Client(1)[0], "", trans).ConfigureAwait(false);

            try
            {
                //await database.AddAsync<BookEntity>(books[0], "", trans);

                await database.BatchAddAsync(books, "x", trans).ConfigureAwait(false);

                await _sqlIteTransaction.CommitAsync(trans).ConfigureAwait(false);
            }
            catch
            {
                await _sqlIteTransaction.RollbackAsync(trans).ConfigureAwait(false);
            }


            Stopwatch stopwatch = new Stopwatch();

            using SqliteConnection mySqlConnection = new SqliteConnection("Data Source=sqlite_test2.db");



            //time = 0;
            int loop = 10;

            TimeSpan time0 = TimeSpan.Zero, time1 = TimeSpan.Zero, time2 = TimeSpan.Zero, time3 = TimeSpan.Zero;

            for (int cur = 0; cur < loop; ++cur)
            {
                await mySqlConnection.OpenAsync().ConfigureAwait(false);


                using SqliteCommand command0 = new SqliteCommand("select * from tb_bookentity_client limit 1000", mySqlConnection);

                SqliteDataReader?reader0 = await command0.ExecuteReaderAsync().ConfigureAwait(false);

                List <BookEntity_Client> list1 = new List <BookEntity_Client>();
                List <BookEntity_Client> list2 = new List <BookEntity_Client>();
                List <BookEntity_Client> list3 = new List <BookEntity_Client>();

                int len = reader0.FieldCount;
                EntityPropertyDef[] propertyDefs = new EntityPropertyDef[len];
                MethodInfo[]        setMethods   = new MethodInfo[len];

                EntityDef definition = EntityDefFactory.GetDef <BookEntity_Client>() !;

                for (int i = 0; i < len; ++i)
                {
                    propertyDefs[i] = definition.GetPropertyDef(reader0.GetName(i)) !;
                    setMethods[i]   = propertyDefs[i].SetMethod;
                }


                Func <IDataReader, object> mapper1 = EntityMapperDelegateCreator.CreateToEntityDelegate(definition, reader0, 0, definition.FieldCount, false, Database.Engine.EngineType.SQLite);


                //Warning: 如果用Dapper,小心DateTimeOffset的存储,会丢失offset,然后转回来时候,会加上当地时间的offset
                TypeHandlerHelper.AddTypeHandlerImpl(typeof(DateTimeOffset), new DateTimeOffsetTypeHandler(), false);
                Func <IDataReader, object> mapper2 = DataReaderTypeMapper.GetTypeDeserializerImpl(typeof(BookEntity_Client), reader0);



                Stopwatch stopwatch1 = new Stopwatch();
                Stopwatch stopwatch2 = new Stopwatch();
                Stopwatch stopwatch3 = new Stopwatch();

                while (reader0.Read())
                {
                    stopwatch1.Start();

                    object obj1 = mapper1(reader0);

                    list1.Add((BookEntity_Client)obj1);
                    stopwatch1.Stop();



                    stopwatch2.Start();
                    object obj2 = mapper2(reader0);

                    list2.Add((BookEntity_Client)obj2);
                    stopwatch2.Stop();


                    stopwatch3.Start();

                    BookEntity_Client item = new BookEntity_Client();

                    for (int i = 0; i < len; ++i)
                    {
                        EntityPropertyDef property = propertyDefs[i];

                        object?value = TypeConvert.DbValueToTypeValue(reader0[i], property, Database.Engine.EngineType.SQLite);

                        if (value != null)
                        {
                            setMethods[i].Invoke(item, new object?[] { value });
                        }
                    }

                    list3.Add(item);

                    stopwatch3.Stop();
                }

                time1 += stopwatch1.Elapsed;
                time2 += stopwatch2.Elapsed;
                time3 += stopwatch3.Elapsed;

                await reader0.DisposeAsync().ConfigureAwait(false);

                command0.Dispose();

                await mySqlConnection.CloseAsync().ConfigureAwait(false);
            }

            _output.WriteLine("Emit Coding : " + (time1.TotalMilliseconds / (loop * 1.0)).ToString(CultureInfo.InvariantCulture));
            _output.WriteLine("Dapper : " + (time2.TotalMilliseconds / (loop * 1.0)).ToString(CultureInfo.InvariantCulture));
            _output.WriteLine("Reflection : " + (time3.TotalMilliseconds / (loop * 1.0)).ToString(CultureInfo.InvariantCulture));
        }