studio - LINQ to SQL-
linq to sql visual studio 2017 (14)
Dado que no se está llamando a la base de datos, creo que hay que mirar las asignaciones que está utilizando linq para sql. ¿Cómo se ve la Asociación? Debería haber una Asociación en las clases de padres e hijos. Eche un vistazo a la asociación de linq a sql entre las dos clases. La Asociación debe tener una propiedad ThisKey. El reparto que está fallando trata de arrojar el valor de la propiedad a la que apunta ThisKey, creo. Por lo que puedo decir, puede haber un problema cuando hay más de una clave y el tipo de la primera clave no coincide con el tipo que ThisKey señala también. No estoy seguro de cómo linq determinaría cuál es la primera clave. Por lo que se ve, solo tiene una clave y una clave externa, así que ese no debería ser el problema, pero se sabe que el diseñador, si lo está utilizando, se vuelve creativo. Estoy adivinando, pero esto parece algo que he visto antes.
Estoy intentando utilizar LINQ para insertar un registro en una tabla secundaria y recibo un error de "error de conversión especificado no válido" que tiene algo que ver con las claves involucradas. El seguimiento de la pila es:
Mensaje: el lanzamiento especificado no es válido.
Tipo: System.InvalidCastException Origen: System.Data.Linq TargetSite: Boolean TryCreateKeyFromValues (System.Object [], V ByRef) HelpLink: nulo Stack: en System.Data.Linq.IdentityManager.StandardIdentityManager.SingleKeyManager
2.TryCreateKeyFromValues(Object[] values, V& v) at System.Data.Linq.IdentityManager.StandardIdentityManager.IdentityCache
2.Find (Object [] keyValues) en System.Data.Linq.IdentityManager.StandardIdentityManager.Find (tipo MetaType, Object [] keyValues) en System. Data.Linq.CommonDataServices.GetCachedObject (Tipo MetaType, Object [] keyValues) en System.Data.Linq.ChangeProcessor.GetOtherItem (MetaAssociation assoc, instancia Object) en System.Data.Linq.ChangeProcessor.BuildEdgeMaps () en System.Data. Linq.ChangeProcessor.SubmitChanges (ConflictMode failureMode) en System.Data.Linq.DataContext.SubmitChanges (ConflictMode failureMode) en System.Data.Linq.DataContext.SubmitChanges ()(.....)
Este error se está lanzando en el siguiente código:
ResponseDataContext db = new ResponseDataContext(m_ConnectionString);
CodebookVersion codebookVersion = db.CodebookVersions.Single(cv => cv.VersionTag == m_CodebookVersionTag);
ResponseCode rc = new ResponseCode()
{
SurveyQuestionName = "Q11",
Code = 3,
Description = "Yet another code"
};
codebookVersion.ResponseCodes.Add(rc);
db.SubmitChanges(); //exception gets thrown here
Las tablas en cuestión tienen una relación FK entre los dos.
La columna de la tabla principal se llama ''id'', es PK y es de tipo: INT INTENSIDAD NULA
La columna de la tabla hija se llama ''responseCodeTableId'' y es de tipo: INT NOT NULL.
codebookVersion (clase principal) se asigna a la tabla tblResponseCodeTable
responseCode (childClass) se asigna a la tabla tblResponseCode
Si ejecuto SQL directamente, funciona. p.ej
INSERT INTO tblResponseCode
(responseCodeTableId, surveyQuestionName, code, description)
VALUES (13683, ''Q11'', 3, ''Yet another code'')
Las actualizaciones de la misma clase funcionan correctamente. p.ej
codebookVersion.ResponseCodes[0].Description = "BlahBlahBlah";
db.SubmitChanges(); //no exception - change is committed to db
He examinado la variable, rc, después de la operación .Add () y, de hecho, recibo el responseCodeTableId adecuado, tal como esperaría, ya que lo estoy agregando a esa colección.
tblResponseCodeTable''s full definition:
COLUMN_NAME TYPE_NAME
id int identity
responseCodeTableId int
surveyQuestionName nvarchar
code smallint
description nvarchar
dtCreate smalldatetime
dtCreate tiene un valor predeterminado de GetDate ().
El único resto de información útil que puedo pensar es que nunca se prueba ningún SQL en contra de la base de datos, por lo que LINQ está explotando antes de intentarlo (de ahí que el error no sea una SqlException). He perfilado y verificado que no se intenta ejecutar ninguna declaración en la base de datos.
He leído y visto el problema cuando tienes una relación con un campo PK no, pero eso no se ajusta a mi caso.
¿Alguien puede arrojar algo de luz sobre esta situación para mí? ¿Qué cosa increíblemente obvia me estoy perdiendo aquí?
Muchas gracias.
Paul Prewett
Este bloque:
codebookVersion.ResponseCodes.Add(rc);
db.SubmitChanges(); //exception gets thrown here
¿Puedes probar InsertOnSubmit
lugar de Add
? es decir
codebookVersion.ResponseCodes.InsertOnSubmit(rc);
Creo que Add
no está destinado a ser utilizado para insertar registros si mi memoria no me falla. InsertOnSubmit es el que se debe usar.
Para tratar de reducir al culpable.
¿Has intentado reemplazar el diccionario anónimo con algo como:
ResponseCode rc = new ResponseCode();
rc.SurveyQuestName = "Q11";
rc.Code = 3;
rc.Description = "Yet Another Code";
Todavía tengo que trabajar realmente con .NET 3.5 (el trabajo diario todavía es 2.0), así que me pregunto si hay un problema al pasar los datos usando el diccionario anónimo (los casos no coinciden con las columnas SQL para uno).
Publica el esquema de la tabla principal.
si miras aquí, algunas otras personas han tenido tu problema. http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=3493504&SiteID=1
Parece que Linq2SQL tiene problemas para asignar algunas claves externas a algunas claves primarias. Un hombre tenía una resolución, pero creo que ya estás mapeando en una columna de IDENTIDAD.
Sí, he leído eso y otras publicaciones, pero siempre parece involucrar a alguien que se vincula a un campo que simplemente tiene un único inconveniente. O en el caso de este tipo (que suena exactamente como el mío), no obtuvo una solución.
Aquí está la tabla padre:
tblResponseTable definition (which maps to CodebookVersion)
COLUMN_NAME TYPE_NAME
id int identity
versionTag nvarchar
responseVersionTag nvarchar
versionTag tiene una desventaja única en él, pero eso no está representado en ningún lugar que pueda ver en el material LINQ-to-SQL, y dado que nada va a la base de datos ... todavía está atascado.
ResponseCode rc = new ResponseCode()
{
SurveyQuestionName = "Q11",
Code = 3,
Description = "Yet another code"
};
y:
INSERT INTO tblResponseCode
(responseCodeTableId, surveyQuestionName, code, description)
VALUES (13683, ''Q11'', 3, ''Yet another code'')
No son lo mismo, no está pasando la referencia de clave externa. Ahora, soy enorme n00b en LINQ2SQL, pero apostaría que LINQ2SQL no es lo suficientemente inteligente como para hacer eso por usted, y lo espera como el primer parámetro del diccionario anónimo, y está tratando de convertir una cadena en un entero .
Solo algunas ideas
ResponseCode rc = new ResponseCode()
{
CodebookVersion = codebookVersion,
SurveyQuestionName = "Q11",
Code = 3,
Description = "Yet another code"
};
db.ResponseCodes.InsertOnSubmit(rc);
db.SubmitChanges();
Es posible que desee verificar que los campos en las tablas de la base de datos que establece el servidor de base de datos cuando inserta un nuevo registro tengan reflejados en el diagrama de Linq a SQL. Si selecciona un campo en el diagrama de Linq a SQL y visualiza sus propiedades, verá un campo llamado "Valor generado automáticamente" que, si se establece en verdadero, garantizará que todos los registros nuevos adopten el valor predeterminado especificado en la base de datos.
LINQ to SQL ha sido desaprobado, FYI - http://blogs.msdn.com/adonet/archive/2008/10/29/update-on-linq-to-sql-and-linq-to-entities-roadmap.aspx .
En algún lugar de su gráfico objeto hay un error de conversión, el modelo de datos subyacente (o el modelo Linq To SQL) ha cambiado. Esto es típicamente algo así como NVARCHAR (1) -> CHAR cuando debería ser STRING, o algo similar.
Este error no es divertido de buscar, con suerte su modelo de objetos es pequeño.
¿Es este un ejemplo de este error ? Si es así, intente ejecutar su código en .NET 4.0 ahora que la versión beta está desactivada.
Si, como yo, no está listo para comenzar a utilizar la versión beta, puede evitar el problema. El problema parece ser que LINQ no admite correctamente las relaciones definidas en campos clave no primarios. Sin embargo, el término "clave principal" no se refiere a la clave primaria definida en la tabla SQL, sino a la clave primaria definida en el diseñador LINQ.
Si arrastró sus tablas al diseñador, entonces Visual Studio inspecciona automáticamente la clave principal definida en la base de datos y marca los campos de clase correspondientes como "claves principales". Sin embargo, estos no necesitan corresponderse entre sí. Puede eliminar la clave que Visual Studio eligió para usted y elegir otro campo (o grupo de campos). Por supuesto, debe asegurarse de que esto sea lógico (debe tener una restricción única en la base de datos en el campo / campos que elija).
Así que tuve 2 tablas / clases relacionadas entre sí utilizando una clave alternativa. La tabla padre tenía 2 claves: una clave primaria sustituta definida como int, y una clave natural alternativa definida como una cadena. En el diseñador de LINQ, había definido la asociación usando la clave alternativa, y experimenté InvalidCastException cada vez que intentaba actualizar ese campo de asociación en el objeto hijo. Para solucionar este problema, entré en el diseñador de LINQ, seleccioné el int y luego cambié la propiedad de la clave principal de True a False. Luego elegí la cadena y establecí su propiedad de clave primaria en True. Se volvió a compilar, se volvió a probar y la InvalidCastException desapareció.
En cuanto a la captura de pantalla, parece que puede solucionar el problema cambiando la clave principal LINQ en ResponseCode de ResponseCode.ID a ResponseCode.ResponseCodeTableID
Tuvimos un problema similar, causado por el uso de claves no enteras. Detalles y número de revisión están aquí: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=351358
Mike, te escucho. Pero no importa dónde miro, todo parece correcto. Revisé y volví a comprobar que ResponseTableId es un int y que Id es un int. Se definen como tales en el diseñador y cuando voy a ver el código generado, parece que todo vuelve a estar en orden.
He examinado las asociaciones. Aquí están:
[Table(Name="dbo.tblResponseCode")]
public partial class ResponseCode : ...
...
[Association(Name="CodebookVersion_tblResponseCode", Storage="_CodebookVersion", ThisKey="ResponseCodeTableId", OtherKey="Id", IsForeignKey=true)]
public CodebookVersion CodebookVersion
{
...
}
[Table(Name="dbo.tblResponseCodeTable")]
public partial class CodebookVersion : ...
...
[Association(Name="CodebookVersion_tblResponseCode", Storage="_ResponseCodes", ThisKey="Id", OtherKey="ResponseCodeTableId")]
public EntitySet<ResponseCode> ResponseCodes
{
...
}
Y una captura de pantalla de la asociación en caso de que ayude:
¿Alguna idea adicional?
Me encontré con un problema muy similar. Lo vincularé a mi mensaje de Wordy: http://forums.asp.net/p/1223080/2763049.aspx
Y también ofreceré una solución, solo una suposición ...
ResponseDataContext db = new ResponseDataContext(m_ConnectionString);
CodebookVersion codebookVersion = db.CodebookVersions.Single(cv => cv.VersionTag == m_CodebookVersionTag);
ResponseCode rc = new ResponseCode()
{
ResponseCodeTableId = codebookVersion.Id,
SurveyQuestionName = "Q11",
Code = 3,
Description = "Yet another code"
};
db.ResponseCodes.InsertOnSubmit(rc);
db.SubmitChanges();