2008-08-15 21 views
13

Tenemos nuestro propio ORM que utilizamos aquí, y ofrecemos envoltorios fuertemente tipados para todas nuestras tablas db. También permitimos que se ejecute SQL ad hoc débilmente tipeado, pero estas consultas aún pasan por la misma clase para obtener valores de un lector de datos.Acceso a la base de datos C#: DBNull vs null

Al ajustar esa clase para trabajar con Oracle, nos hemos encontrado con una pregunta interesante. ¿Es mejor usar DBNull.Value o null? ¿Hay algún beneficio al usar DBNull.Value? Parece más "correcto" usar null, ya que nos hemos separado del mundo de DB, pero hay implicaciones (no se puede simplemente a ciegas ToString() cuando un valor es nulo, por ejemplo), así que definitivamente es algo que necesitamos hacer. decisión consciente acerca de.

Respuesta

15

Encuentro que es mejor utilizar nulo, en lugar de DB nulo.

La razón es porque, como dijiste, te estás separando del mundo de DB.

En general, es una buena práctica verificar los tipos de referencia para asegurarse de que no son nulos de todos modos. Comprobará nulo para otras cosas que no sean datos de BD, y creo que es mejor mantener la coherencia en todo el sistema y usar null, no DBNull.

En el largo plazo, arquitectónicamente considero que es la mejor solución.

3

Según la experiencia que he tenido, los .NET DataTables y TableAdapters funcionan mejor con DBNull. También abre algunos métodos especiales cuando está fuertemente tipado, como DataRow.IsFirstNameNull cuando está en su lugar.

Ojalá pudiera darle una mejor respuesta técnica que eso, pero para mí la conclusión es utilizar DBNull cuando se trabaja con los objetos relacionados con la base de datos y luego usar un nulo "estándar" cuando trato con objetos y. Código relacionado con NET.

1

Use DBNull.
Buscamos algún tipo de problema cuando usamos null.
Si recuerdo correctamente, no puede INSERTAR un valor nulo en un campo, solo DBNull.
Podría estar relacionado con Oracle solo, lo siento, ya no sé los detalles.

7

Si ha escrito su propio ORM, entonces diría que simplemente use nulo, ya que puede usarlo como quiera. Creo que DBNull se usó originalmente para evitar el hecho de que los tipos de valor (int, DateTime, etc.) no podían ser nulo, entonces en lugar de devolver algún valor como cero o DateTime.Min, lo que implicaría implicaría nulo (malo, malo), crearon DBNull para indicar esto. Tal vez había algo más, pero siempre supuse que esa era la razón. Sin embargo, ahora que tenemos tipos anulables en C# 3.0, DBNull ya no es necesario. De hecho, LINQ to SQL solo usa null en todo el lugar. No hay problema. Abraza el futuro ... usa null. ;-)

+0

Creo que todavía hay algunos usos para DBNull. Al menos con sqlite puedo probar si un valor devuelto por ExecuteScalar() se almacena explícitamente en la base de datos o no. Considere la tabla foo (a int, b int); con una sola fila (1, nulo). Si tuviéramos que EjecutarScalar en un comando "SELECCIONE b FROM foo WHERE A = 1", devolvería DBNull.Value (la fila existe se almacena un valor nulo). Si tuviera que llamar a ExecuteScalar en "SELECCIONAR b FROM foo DONDE A = 2" devolvería nulo (no existe tal fila). Es de suponer que podría lograr el mismo resultado con un DataReader pero aprecio la conveniencia. – fostandy

+0

Interesante. Al utilizar un ORM para el acceso a la base de datos, a menudo no uso explícitamente ExecuteScalar en mi código. Por lo general, termino recuperando objetos de entidad completos y mirando sus valores de esa manera. Entonces, si la entidad misma es nula, eso es una cosa, y si el valor es nulo, eso es otra cosa. Solo diferentes formas de hacerlo.Reconozco que ExecuteScalar es más eficiente si solo necesitas un solo valor. – jeremcc

Cuestiones relacionadas