¿Por qué Anko no puede ignorar el valor pasado de _id cuando _id es INTEGER + PRIMARY_KEY + AUTOINCREMENT?

He diseñado el campo _id es INTEGER + PRIMARY_KEY+ AUTOINCREMENT , uso el código SettingManage().addSetting(MSetting(10L,"My Settings",2000L,"This is description!")) Para insert un logging en la tabla.

Creo que Anko ignorará el valor pasado 10 de _id y pasará un nuevo valor a _id automáticamente, pero de hecho el valor 10 de _id se inserta en la tabla.

¿Cómo puede hacer que Anko ignore el valor pasado de _id cuando _id es INTEGER + PRIMARY_KEY+ AUTOINCREMENT ?

Insertar datos

 SettingManage().addSetting(MSetting(10L,"My Settings",2000L,"This is description!")) 

Mesa de layout

  class DBSettingHelper(mContext: Context = UIApp.instance) : ManagedSQLiteOpenHelper( mContext, DB_NAME, null, DB_VERSION) { companion object { val DB_NAME = "setting.db" val DB_VERSION = 5 val instance by lazy { DBSettingHelper() } } override fun onCreate(db: SQLiteDatabase) { db.createTable( DBSettingTable.TableNAME , true, DBSettingTable._ID to INTEGER + PRIMARY_KEY+ AUTOINCREMENT , DBSettingTable.Name to TEXT, DBSettingTable.CreatedDate to INTEGER, DBSettingTable.Description to TEXT ) } override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { db.dropTable(DBSettingTable.TableNAME, true) onCreate(db) } } class DBSetting(val mMutableMap: MutableMap<String, Any?>) { var _id: Long by mMutableMap var name: String by mMutableMap var createdDate: Long by mMutableMap var description: String by mMutableMap constructor(_id: Long, name: String, createdDate: Long, description: String) : this(HashMap()) { this._id = _id this.name = name this.createdDate = createdDate this.description=description } } object DBSettingTable { val TableNAME = "SettingTable" val _ID = "_id" val Name = "name" val CreatedDate = "createdDate" val Description="description" } data class MSetting ( val _id: Long, val name: String, val createdDate: Long, val description: String ) 

Lógica de negocios

 class SettingManage { fun addSetting(mMSetting:MSetting){ DBSettingManage().addDBSetting(DbDataMapper().convertMSetting_To_DBSetting(mMSetting)) } } class DBSettingManage(private val mDBSettingHelper: DBSettingHelper =DBSettingHelper.instance) { fun addDBSetting(mDBSetting: DBSetting)=mDBSettingHelper.use{ insert(DBSettingTable.TableNAME,*mDBSetting.mMutableMap.toVarargArray()) } } class DbDataMapper { fun convertMSetting_To_DBSetting(mMSetting: MSetting) =with(mMSetting){ DBSetting(_id,name,createdDate,description) } fun convertDBSetting_To_MSetting(mDBSetting: DBSetting)=with(mDBSetting){ MSetting(_id,name,createdDate,description ) } } fun <T : Any> SelectQueryBuilder.parseList(parser: (Map<String, Any?>) -> T): List<T> = parseList(object : MapRowParser<T> { override fun parseRow(columns: Map<String, Any?>): T = parser(columns) }) 

Anko, en tu uso, es un contenedor para SQLite. SQL en sí anula el incremento automático cuando se pasa un valor personalizado . Si no se pasa ningún valor -> Valor automático. De lo contrario -> manual. Asume que es único debido a PRIMARY_KEY , pero ese es un problema diferente.

Por lo que yo sé, no hay una característica integrada en Anko que permita anular esto manualmente. En cambio, lo único que puede hacer es no pasar un valor. Cualquier consulta SQL que sea incorrecta no será capturada por Anko, sino por el SQL sin formatting. Es SQL el que arroja cualquier exception, lo que significa que Anko no comprobará si faltan datos.

Simplemente, no pase una identificación. Puede escribir una function que aún tome la ID, pero la descarta si la fila está configurada en PRIMARY_KEY y AUTO_INCREMENT.


He profundizado más en el código fuente y no hay soporte para ignorar los valores pasados ​​si está configurado para incrementar automáticamente.

Esto significa que la única forma en que puede lograr que aumente de manera automática es al no pasar ningún valor. Si está utilizando consultas manuales de cualquier tipo, simplemente no pasa ningún valor. Por lo tanto, no le des a la database la ID. Debido a que es un incremento automático, lo agregará automáticamente y estará en el nivel base de SQL.

Ank no lo ignora por defecto porque es esencialmente un contenedor para SQLite. Lo que significa que tiene que poder aprobarse si la ID debe ser anulada (ver el enlace en la segunda oración de esta respuesta). Como tal, Anko ignorarlo causaría más problemas de lo que sería bueno. Debes asegurarte de que no se pase en su lugar

  • Kotlin coroutines en Android: ¿Por qué usar bg () de Anko en lugar de async ()?
  • Seleccionar datos de dos tablas en Kotlin Anko