2008-10-14 10 views
14

Tengo una base de datos de SQL Server con una tabla con los siguientes campos:¿Cómo me aseguro de que Linq a Sql no anule ni viole valores predeterminados de DB que no aceptan nulos?

  1. Un bit con el valor predeterminado 1, NOT NULL.
  2. A smalldatetime con el valor predeterminado gettime(), NOT NULL.
  3. Un int sin valor predeterminado, IDENTITY, NOT NULL.

Cuando genero LINQ to SQL para esta tabla, ocurre lo siguiente:

  1. El bit se da ningún tratamiento especial.
  2. El smalldatetime no ofrece un tratamiento especial.
  3. El int está marcado como IsDbGenerated.

Esto significa que cuando hago insertos utilizando LINQ a SQL, sucederá lo siguiente:

  1. El bit se enviará como 0, anulando el valor predeterminado. ¿Correcto?
  2. El smalldatetime se enviará como un System.DateTime sin inicializar, produciendo un error en el servidor SQL, ya que no se corresponde con el rango de Smalldatetime de SQL Server. ¿Correcto?
  3. No se enviará IsDbGeneratedint; el DB generará un valor que Linq to SQL luego volverá a leer.

¿Qué cambios debo hacer para que este escenario funcione?

En resumen: quiero campos que no admiten nulos con valores predeterminados asignados por DB, pero no los quiero IsDbGenerated si significa que no puedo proporcionarles valores cuando realizo actualizaciones o inserciones utilizando Linq a SQL. Tampoco los quiero IsDbGenerated si esto significa que tengo que modificar a mano el código generado por Linq a SQL.

EDITAR: La respuesta parece ser que esta es una limitación en el actual Linq a SQL.

+0

Duplicado: http://stackoverflow.com/q/1120858/11683 (no votando para cerrar, ambos son igualmente útiles). – GSerg

Respuesta

5

Las clases generadas de Linq-A-SQL no recogen los valores predeterminados.

Tal vez en el futuro, pero el problema es que las limitaciones no son siempre valores simples, sino que también pueden ser funciones escalares como GetDate(), por lo que linq de alguna manera tendría que saber cómo traducirlas. En resumen, ni siquiera lo intenta. También es un tipo de cosas muy específicas de la base de datos.

  • Puede escribir un generador de código para crear clases parciales de entidad donde puede extraer el valor predeterminado constriant.
  • Como alternativa, el código de la capa de su empresa podría establecer los valores predeterminados en los constructores desde un archivo xml, y todo lo que necesita hacer es mantener el archivo xml actualizado.
  • En lugar de hacer el trabajo en constructores, puede emular sql y agregar valores predeterminados inspeccionando el conjunto de cambios antes de enviar cambios a la base de datos.

El problema que tiene es descrito en detalle en CodeProject - Setting Default Values for LINQ Bound Data

+1

"linq de alguna manera tendría que saber cómo traducir esos" - ¿por qué? Simplemente podría permitir que no se pase nada en crear/actualizar, y leerlos luego. Así es como funcionan los campos IsDbGenerated, a excepción de su estado de solo lectura en el lado de Linq. – bzlm

+0

Claro, podría permitirlo, pero no es así. IsDbGenerated es solo para columnas clave en este momento. El "linq de alguna manera ..." es solo mi opinión sobre por qué este puede ser el caso. –

+0

parece que IsDbGenerated ahora también está disponible para columnas que no son clave. –

2

Esto significa que cuando hago insertos utilizando LINQ a SQL, lo siguiente será suceder:

  1. El bit será enviado como 0, anulando el valor predeterminado. ¿Derecha? - correcta
  2. El smalldatetime se enviará como un System.DateTime no inicializado, producir un error en el servidor SQL desde que no se caiga con la gama smalldatetime SQL Server . ¿Derecha?- Lo que se envía es DateTime.MinValue
  3. El IsDbGenerated int no se enviará; el DB generará un valor que Linq to SQL luego volverá a leer. - Si se genera DB generado, la base de datos crea el valor; si no, Linq espera que el usuario establezca el valor.

Su mejor apuesta es para ponerlos en el constructor del objeto, o en los campos privados, si no está utilizando propiedades automáticas.

+0

Parece que está diciendo que los valores predeterminados en los campos en los valores de SQL Server NO son posibles de combinar con Linq To SQL. ¿Es esto correcto? – bzlm

+0

Es posible pero no puede cambiarlos después del hecho. Si desea poder cambiarlos, debe crearlos en el constructor. –

+0

Lo siento, no entiendo. ¿Que es posible? ¿Y qué no se puede cambiar después de qué hecho? ¿Es posible hacer que Linq To SQL realice una inserción y tenga los "valores predeterminados" especificados en la base de datos utilizada? – bzlm

0

Puede crear otro archivo para su contexto de datos (clase parcial) y luego utilizar los métodos parciales InsertYOURENTITY y UpdateYOURENTITY para inspeccionar sus propiedades y asignar los valores adecuados. Llamar a ExecuteDynamicInsert o ExecuteDynamicUpdate después de su código y listo.

+0

En realidad, la forma recomendada de hacerlo en el BLL es implementar el método parcial OnCreated() para la entidad, no el método que sugiera. Aún así, no es relevante para mi pregunta. Mi pregunta es acerca de los valores predeterminados en SQL Server, no en el BLL. – bzlm

3

me he encontrado con el mismo problema, bzlm, y llegar a la misma conclusión. Simplemente no hay una buena manera de obtener campos que no admiten nulos con valores predeterminados asignados por DB que funcionen con Linq To Sql.

El trabajo que me he dado es agregar un método SetDefaults() muy similar al que Robert Paulson vinculó en CodeProject y llamarlo en el constructor predeterminado de la clase base de mi entidad de tabla. Funciona bien para mí, porque el 95% de las veces, estoy configurando un 0, cadena vacía o getdate().

+0

Sí, lo mismo aquí. ¡Gracias! – bzlm

Cuestiones relacionadas