2009-04-15 21 views
7

Tengo una base de datos que es parte de un esquema de Combinación de Replicación que tiene un GUID ya que es PK. Específicamente, el tipo de datos es uniqueidentifier, valor predeterminado (newsequentialid()), RowGUID se establece en . Cuando hago un InsertOnSubmit (CaseNote) pensé que podría dejar CaseNoteID solo y la base de datos ingresaría el siguiente GUID secuencial como lo hace si ingresa manualmente una nueva fila en MSSMS. En su lugar, envía 00000000-0000-0000-0000-000000000000. Si agrego CaseNoteID = Guid.NewGuid(), obtengo un GUID pero no uno secuencial (estoy bastante seguro).LINQ to SQL Insertar GUID Secuencial

¿Hay alguna manera de permitir que SQL cree la siguiente ID secuencial en un LINQ InsertOnSubmit()?

Para referencia a continuación, se encuentra el código que estoy usando para insertar un nuevo registro en la base de datos.

  CaseNote caseNote = new CaseNote 
           { 
            CaseNoteID = Guid.NewGuid(), 
            TimeSpentUnits = Convert.ToDecimal(tbxTimeSpentUnits.Text), 
            IsCaseLog = chkIsCaseLog.Checked, 
            ContactDate = Convert.ToDateTime(datContactDate.Text), 
            ContactDetails = memContactDetails.Text 
           }; 
     caseNotesDB.CaseNotes.InsertOnSubmit(caseNote); 

     caseNotesDB.SubmitChanges(); 

Sobre la base de una de las siguientes sugerencias que permitieron a los generados automáticamente en LINQ para esa columna y ahora me sale el siguiente error ->La tabla de destino de la instrucción DML no puede tener desencadenadores habilitados si la instrucción contiene una cláusula OUTPUT sin cláusula INTO. Ideas?

Respuesta

5

En el diseñador de Linq a Sql, establezca la propiedad Valor generado automáticamente en verdadero para esa columna.

Esto es equivalente al IsDbGenerated property para una columna. La única limitación es que no puede actualizar el valor usando Linq.

+0

He intentado esto y ahora me sale el siguiente error -> La tabla de destino de la instrucción DML no puede tener desencadenadores habilitados si la instrucción contiene una cláusula OUTPUT sin la cláusula INTO. –

+0

¿por qué aceptaste la respuesta si no funciona? – guiomie

+0

Para mí, esto ya estaba configurado, pero la base de datos aún intenta asignar el guí de 0 predeterminado en lugar de generar uno. – DCShannon

5

Desde la parte superior de la caja "relacionada" a la derecha:

Sequential GUID in Linq-to-Sql?

Si realmente desea que el valor "siguiente", utilice un Int64 en lugar de GUID. COMB GUID se asegurará de que los GUID estén ordenados.

+2

+1. Si quiere orden, use un tipo numérico. Las guías se diseñaron para funcionar como identificadores únicos, no proporcionan ningún método de ordenación. –

+0

cierto, pero puede causar una gran cantidad de abandono en dos casos: indexación en clúster y rendimiento de replicación (que se parece al problema del OP).COMB ayuda con eso, pero no necesariamente los convierte en secuenciales. –

+0

@Michael - gracias por señalar eso. Es extraño que no fue una de las "sugerencias" cuando creé el título –

1

Con respecto a su "La tabla de destino de la declaración DML no puede tener disparadores habilitados si la instrucción contiene una cláusula OUTPUT sin cláusula INTO", consulte este artículo de MS KB, parece ser un error en LINQ:

http://support.microsoft.com/kb/961073

1

realmente se necesita para hacer un par de cosas.

  1. Retire cualquier asignación a la propiedad de tipo GUID
  2. Cambio de la columna para autogenerado
  3. crea una restricción en la base de datos por defecto de la columna para NEWSEQUENTIALID()
  4. No inserte en enviar al igual que eras antes de.

En la inserción en la tabla, se creará la ID y será secuencial. Performance comparison of NEWSEQUENTIALID() vs. other methods

+0

@C Tierney: ¿Cómo difiere esto de la solución aceptada? Suena como lo mismo, simplemente explicado, ¿correcto? –

0

MassTransit utiliza un combguid:

https://github.com/MassTransit/MassTransit/blob/master/src/MassTransit/NewId/NewId.cs

es esto lo que está buscando?

de Wikipedia:

algoritmos secuenciales

GUID se utilizan comúnmente como la clave principal de las tablas de bases de datos, y con eso, a menudo la tabla tiene un índice agrupado en ese atributo. Esto presenta un problema de rendimiento cuando se insertan registros porque un GUID completamente aleatorio significa que es posible que el registro deba insertarse en cualquier lugar dentro de la tabla en lugar de simplemente anexarse ​​cerca del final del mismo. Como una forma de mitigar este problema al mismo tiempo que proporciona suficiente aleatoriedad para evitar efectivamente colisiones de números duplicados, se han utilizado varios algoritmos para generar GUID secuenciales. La primera técnica, descrita por Jimmy Nilsson en agosto de 2002 [7] y referida como "COMB" ("guid/timestamp combinado"), reemplaza los últimos 6 bytes de Data4 con los 6 bytes menos significativos de la fecha/hora actual del sistema. Si bien esto puede dar como resultado GUIDs que se generan fuera de orden dentro de en la misma fracción de segundo, sus pruebas mostraron que esto tuvo poco impacto en la inserción en el mundo real . Un efecto secundario de este enfoque es que la fecha y hora de inserción se pueden extraer fácilmente del valor más tarde, si se desea. Comenzando con Microsoft SQL Server versión 2005, Microsoft agregó una función al lenguaje Transact-SQL llamado NEWSEQUENTIALID(), [8] que genera GUIDs que están garantizados a aumentar en valor, pero puede comenzar con un número menor (aún garantizado) único) cuando el servidor se reinicia. Esto reduce el número de páginas de tabla de la base de datos donde pueden realizarse inserciones, pero no garantiza que los valores siempre aumentarán en valor. Los valores devueltos por esta función se pueden predecir fácilmente, por lo que este algoritmo no es adecuado para generar números oscuros por razones de seguridad o hash. En 2006, un programador descubrió que la función SYS_GUID proporcionada por Oracle devolvía GUID secuenciales en algunas plataformas, pero esto parece ser , es un error en lugar de una característica. [9]

0

Debe manejar OnCreated método()

Partial Class CaseNote 
    Sub OnCreated() 
     id = Guid.NewGuid() 
    End Sub 
End Class