2010-03-31 13 views
10

Tengo una columna de base de datos no anulable que tiene un valor predeterminado establecido. Al insertar una fila, a veces se especifica un valor para la columna, a veces, uno no. Esto funciona bien en TSQL cuando se omite la columna. Por ejemplo, dada la siguiente tabla:¿Puede LINQ-to-SQL omitir columnas no especificadas en Insertar para que se use un valor predeterminado de la base de datos?

CREATE TABLE [dbo].[Table1](
    [id] [int] IDENTITY(1,1) NOT NULL, 
    [col1] [nvarchar](50) NOT NULL, 
    [col2] [nvarchar](50) NULL, 
CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED ([id] ASC) 
) 
GO 
ALTER TABLE [dbo].[Table1] 
    ADD CONSTRAINT [DF_Table1_col1] DEFAULT ('DB default') FOR [col1] 

Las dos instrucciones siguientes trabajarán:

INSERT INTO Table1 (col1, col2) VALUES ('test value', '') 
INSERT INTO Table1 (col2) VALUES ('')  

En la segunda declaración, el valor predeterminado se utiliza para col1.

El problema que tengo es cuando uso LINQ-to-SQL (L2S) con una tabla como esta. Quiero producir el mismo comportamiento, pero no puedo entender cómo hacer que L2S haga eso. Quiero ser capaz de ejecutar el siguiente código y tienen la primera fila obtener el valor especifico y la segunda fila reciben el valor por defecto de la base de datos:

var context = new DataClasses1DataContext(); 
var row1 = new Table1 { col1 = "test value", col2 = "" }; 
context.Table1s.InsertOnSubmit(row1); 
context.SubmitChanges(); 
var row2 = new Table1 { col2 = "" }; 
context.Table1s.InsertOnSubmit(row2); 
context.SubmitChanges(); 

Si el auto generada propiedad Value de col1 es falso, la primera fila se crea como se desea, pero la segunda fila falla con un error nulo en col1. Si Auto Generated Value es True, ambas filas se crean con el valor predeterminado de la base de datos. Probé varias combinaciones de Auto Generated Value, Auto-Sync y Nullable, pero nada de lo que he probado me da el comportamiento que quiero.

L2S no omite la columna de la instrucción de inserción cuando no se especifica ningún valor. En su lugar, hace algo como esto:

INSERT INTO Table1 (col1, col2) VALUES (null, '') 

... que por supuesto provoca un error nulo en col1.

¿Hay alguna manera de hacer que L2S omita una columna de la instrucción de inserción si no se proporciona ningún valor? ¿O hay alguna otra forma de obtener el comportamiento que quiero? Necesito el valor predeterminado en el nivel de la base de datos porque no todas las inserciones en fila se realizan a través de L2S, y en algunos casos el valor predeterminado es un poco más complejo que un valor codificado (por ejemplo, crear el predeterminado en otro campo) así que en lugar de evitar duplicar esa lógica.

Respuesta

7

Desafortunadamente, LINQ to SQL no es compatible con la base de datos por defecto valores. Ver la primera pregunta aquí:

http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/3ae5e457-099e-4d13-9a8b-df3ed4ba0bab/

Lo que estamos sugiriendo es que usted proporciona una implementación del método Insert para la entidad de que se trate. El ser

partial void Insert[EntityName](Entity instance) 

Así que si había una entidad llamada persona, que quería tener un valor por defecto de "Inicio" para un campo PhoneNumberDesc firma, se podría implementar de esta manera:

partial void InsertPerson(Person instance) 
    { 
     if (string.IsNullOrEmpty(instance.PhoneNumberDesc)) 
      instance.PhoneNumberDesc = "Home"; 

     var insertParams = new List<object>(); 
     var insertStatement = "insert into ..."; 

     // build the rest of the insert statement and fill in the parameter values here... 

     this.ExecuteQuery(typeof(Person), insertStatement, insertParams.ToArray()); 
    } 

Es posible que pueda salirse con la suya implementando el evento OnCreated, que se llama con cada constructor para cada entidad.Este artículo explica un poco sobre cómo los puntos de extensibilidad en Linq To SQL: http://msdn.microsoft.com/en-us/library/bb882671.aspx

En general, la solución realmente es una mierda. ¡Buena suerte!

+0

cualquier nueva solución fácil? – Binny

+0

@Binny si es posible, no use Linq-to-SQL, es una tecnología muy antigua, desactualizada y sin soporte. No confundas eso con el uso de Linq con Entity Framework, que debería funcionar perfectamente bien con los valores predeterminados. –

+0

¿Qué tecnología debería seguir para los proyectos? ¿¿alguna sugerencia?? – Binny

-2

no estoy seguro acerca de LINQ, pero en SQL cuando se desea un defecto hacerlo de cualquier manera:

INSERT INTO Table1 (col2) VALUES ('X') 

o

INSERT INTO Table1 (col1, col2) VALUES (DEFAULT, 'X') 
+1

No parece haber una manera de decirle a L2S que use el valor predeterminado. –

Cuestiones relacionadas