2011-04-29 11 views
12

Me enteré para que la clase Android CursorAdapter funcione, necesito una fila _id. Ahora, tengo un esquema de nomenclatura específico y no quiero cambiar mi columna de ID (llamada ID) a _id para todas las tablas para las que necesito CursorAdapters. Creo que esto afectará la legibilidad de algunas de mis consultas complejas, además de que "_id" es feo: P.Solución alternativa para necesitar una fila _id para CursorAdapter

Estoy debatiendo el uso de consultas de selección "TableID como _id" personalizadas, pero me gustan los métodos de consulta agradables de SQLiteDatabase y no parece que admitan el cambio de nombre de columnas en la consulta.

Parece inflexible (y extraño) para requerir siempre un nombre de columna de tabla específico. ¿Hay alguna manera de especificar qué columna usar como columna de id para CursorAdapter? ¿O quizás otra solución alternativa en la que no he pensado?

+1

+1 - ' "_id" es feo: P' –

Respuesta

2

Dos soluciones alternativas serían utilizar un CursorWrapper, o utilizar el ProjectionMap de un ManagedQuery para asignar su uid a_id.

+0

CursorWrapper podría funcionar. No estoy familiarizado con el uso de consultas administradas, pero una búsqueda en google me llevó al método setProjectionMap de SQLiteQueryBuilder, que podría hacer el truco ... – Emily

+0

ManagedQuery funciona con ContentProviders, que implementé en mi proyecto porque estoy tratando de aprender tanto como sea posible ...;) Una solución más sería crear una vista en su base de datos que incluya _id como una de las columnas. –

+1

No pensé en hacer una vista. Gracias por las muchas sugerencias. Ninguno es tan simple como lo que estaba buscando (¡te doy CursorAdapter!), Pero supongo que así es la vida. Gracias de nuevo. – Emily

10

Su base de datos no necesita tener una columna llamada '_id' pero el CursorAdaptor necesita tener una devuelta. Puede hacer esto con un alias (como su idea "TableID como _id") en una rawQuery.

Un ejemplo es que tengo una tabla con columnas ...

uid,name,number 

Para consultar esto por un SimpleCursorAdapter (por ejemplo), lo hago con una base de datos rawQuery ...

db.rawQuery("SELECT uid as _id,name,number FROM MY_TABLE"); 

Esto funciona bien y proporciona la columna '_id' necesaria para SimpleCursorAdapter.

+0

Sí, estaba pensando en eso, pero me prefiere utilizar los métodos .query en la clase SQLiteDatabase en lugar de .rawQuery. Si no hay otra manera, tendré que elegir el menor de los dos males (renombrar la columna O construir mis consultas a mano y usar rawQuery).¿Hay algún otro método además de .rawQuery que me permita cambiar el nombre de las columnas? – Emily

+0

@Emily: Para mi aplicación actual, personalmente encontraría el cambio de nombre de mis columnas DB como el peor mal (especialmente porque estoy duplicando un DB en un sistema remoto) pero obviamente variará de dev a desarrollador y aplicación a aplicación . En el punto de utilizar los métodos de consulta SQLiteDatabase, una vez más una observación personal, pero siempre he usado SQL 'en bruto' como programo con diferentes idiomas y diferentes plataformas. Raw SQL es portable y también he visto algunos ejemplos verdaderamente horribles aquí en SO de personas que intentan realizar consultas complejas utilizando los métodos de consulta SQLiteDatabase. – Squonk

12

No es necesario utilizar una consulta cruda, CursorWrapper, etc. Puede hacer exactamente lo que mencionó: cuando especifique las columnas para su consulta, simplemente especifique "TableID como _id" como una de ellas. En realidad, en lugar de _id, usaría BaseColumns._ID. Algo como esto debería funcionar bien:

static final String[] columns = new String[] { 
    "TableID AS " + BaseColumns._ID, 
    ... 
}; 

y luego pasar a lo que usted está utilizando para crear el cursor (SQLiteDatabase, CursorLoader, etc.)

También recomendaría poner los nombres de columna en constantes de cadena a las que puede hacer referencia en su aplicación, por ejemplo MyDatabase.TABLE_ID, entonces el anterior sería MyDatabase.TABLE_ID + " AS " + BaseColumns._ID

0

Se me ocurrió esta solución, con algo de ayuda de esta publicación sequential row numbers from query. Utiliza un campo _id generado. La ventaja aquí es que no necesita meterse con su esquema y obtiene buenos valores _id secuenciales.

Mi código para cargar el Cursor fue el siguiente:

Cursor c = db.rawQuery(
       "SELECT * " 
       +"FROM Sale " 
       +"ORDER BY orderTime " 
       , null); 

I añade el SELECT interna, que requiere un alias en el nombre de tabla exterior. (Nótese cómo t2 se utiliza en el selecto interior, pero se crea en el exterior seleccione)

Cursor c = db.rawQuery(
      "SELECT " 
      +"(select COUNT(0) from Sale t1 where t1.orderTime <= t2.orderTime) as _id,t2.* " 
      +"FROM Sale t2 " 
      +"ORDER BY t2.orderTime " 
      , null); 
Cuestiones relacionadas