relacion muchos c# linq-to-sql entityset

c# - relacion - LINQ-to-SQL+Eliminación de enlace de datos de uno a muchos+



ef muchos a muchos (7)

Gracias por su respuesta, examinaré las publicaciones y veré qué puedo hacer. Debo decir que estoy sorprendido de incluso ver este problema, me parece bastante natural que uno pueda agregar registros al "caché" de datos proporcionado por LINQ, luego decida borrar algunos de ellos y luego confirmarlos. El seguimiento de cambios debería ser capaz de manejar eso. Acabo de empezar con LINQ, así que podría estar cometiendo un error estúpido en algún lugar del código (no sería el primero).

Por otro lado, tiene razón en que el ajo puede pertenecer a muchas recetas (¡no en mis recetas de cócteles!). De hecho, yo modelé eso con un objeto / tabla de artículo. Pero para una receta, necesitas cantidades. Entonces en mi modelo, tienes una Receta que tiene 1: n Ingredientes, cada uno de ellos con una Cantidad, un enlace 1: 1 a un Artículo (que tiene un Nombre, un Contenido de Alcohol y algunos datos para establecer una jerarquía de intercambiabilidad) y un Enlace 1: 1 a una Unidad (para que la cantidad tenga sentido). Entonces, en cierto sentido, la tabla de ingredientes establece una relación M: N entre Receta y Artículo, y al mismo tiempo agrega información adicional a cada par individual vinculado.

Uso LINQ-to-SQL para cargar datos de una base de datos que tiene dos tablas en una relación de uno a varios (una Receta tiene muchos ingredientes).

Cargué una receta y LINQ recupera los objetos de Ingrediente en un EntitySet que está vinculado a un ListBox.

Si deseo eliminar algunos ingredientes de una receta, aparece el mensaje "Se intentó eliminar una relación entre una receta y un ingrediente. Sin embargo, una de las claves externas de la relación (Ingredient.RecipeID) no se puede establecer como nula.

SOLUCIONÉ este problema usando la solución conocida añadiendo ''DeleteOnNull = "true'' ''al archivo DBML. Pero agregar esta configuración solo elimina el problema cuando eliminamos objetos de Ingrediente que se recuperaron de la base de datos.

El problema es con los objetos Ingredientes que se crearon en el código (se agregaron a una Receta) y se agregaron a la colección de Ingredientes EntitySet y luego se eliminaron ANTES de que se llamara Enviar Datos. Entonces, la misma excepción ocurre nuevamente. Esto generalmente sucede en una nueva receta no guardada cuando el usuario agrega ingredientes a ella, comete un error y borra un ingrediente de una receta. Agregué el DeleteOnNull a ambas líneas de ''Nombre de asociación ='' Recipe_Ingredient '''' en DBML.

¿Cómo se supone que debo eliminar esos objetos? La única solución que veo en este momento es que cargaría los ingredientes en una colección que no está en DataContext y luego, al guardarlos, eliminará todos los ingredientes de una receta y los agregará nuevamente desde esa caché.


necesita desacoplar el código de guardado de los eventos en su GUI, parece que está un poco ansioso por guardar cosas en el DB antes de que el polvo se haya asentado y esté haciendo cola y eliminando cosas del DB que nunca llegó allí en primer lugar, sería mejor si identificara un punto cuando el usuario "comprometerá" sus cambios, y en ese momento, procesará el estado completo de la GUI, esto le ahorrará un montón de código de spaghetti.

También me gustaría saber si sus entidades tienen ID autonumerables o si está utilizando algún otro mecanismo de identificación. Probablemente estés enviando DELETE a la base de datos para los registros de Ingrediente aún no comprometidos, si esos incluyen ID NULL, creo que el linq podría volverse desagradable.

¿Ha conectado un editor de texto a DataContext.Log para ver qué tipo de SQL se genera justo antes de obtener su excepción?


try { // Needed for existing records, but will fail for new records yourLINQDataContext.Ingredients.DeleteOnSubmit(ingredient); } catch (Exception) { // Swallow } yourRecipeObject.Ingredients.Remove(ingredient);


Me encuentro con un problema similar, como una solución, tengo que llamar a DataContext.GetChanges (), y luego todo parece haberse puesto de nuevo :)

Otro problema podría ser que sea vinculante para las columnas y no para las propiedades de la entidad y, por lo tanto, las colecciones referenciales no se actualicen (ya lo haya declarado otra persona, pero se haga cumplir).


Tuve exactamente el mismo problema. Tenía una jerarquía padre / hijo, y cuando añadí y eliminé la entidad hija sin guardarla en la base de datos, recibí la excepción "Se intentó eliminar una relación".

Descubrí que este problema solo surgió cuando establecí una propiedad de estilo de objeto del elemento secundario en otra entidad linq-sql antes de guardar. p.ej

1. Esto crea el error

RetailAccountCustomerCard racc = new RetailAccountCustomerCard(); Card addedCard = _idc.Cards.Where(c => c.CardId == card.CardId).ToList().First(); racc.Card = addedCard; this.CurrentCustomer.RetailAccountCardsBindingList.Add(racc); // Some code triggered by the user before saving to the db CurrentCustomer.RetailAccountCardsBindingList.Remove(racc);

2. Esto no crea el error

RetailAccountCustomerCard racc = new RetailAccountCustomerCard(); racc.CardId = card.CardId; // note that I have set the Id property not the object this.CurrentCustomer.RetailAccountCardsBindingList.Add(racc); // Some code triggered by the user before saving to the db CurrentCustomer.RetailAccountCardsBindingList.Remove(racc);

Curiosamente, el error que surge en 1. especifica que el problema tiene que ver con la relación en la propiedad RetailAccountCustomerId de RetailAccountCustomerCard. NO TIENE NADA QUE VER CON EL OBJETO DE LA TARJETA QUE AÑADÍ . Parece que simplemente establecer cualquier propiedad del objeto de la nueva entidad desencadena el problema.

NÓTESE BIEN. El ejemplo 1 funciona bien en términos de ahorro, solo causa un problema si la nueva entidad se elimina antes de guardar.


// Create new entities Cart c = new Cart(); CartEntry ce = new CartEntry(); ce.Cart = c; // Delete the entry c.CartEntries.Remove(ce); dc.Cartentries.Attach(ce); dc.CartEntries.DeleteOnSubmit(ce); // Insert the cart into database dc.Carts.InsertOnSubmit(c); dc.SubmitChanges();

Explicación del problema: Ambas entidades, c y ce, no están relacionadas con un contexto de datos: no están siendo rastreados. EntitySet.Remove () (primera línea de eliminación) solo elimina la relación entre c y ce. Mientras que c puede existir sin entradas de carrito asociadas, ce no puede existir sin un carro asignado debido a una restricción de clave externa. Al enviar cambios a la base de datos, también se trata el ce desconectado, causando una violación de restricción y la excepción.

Para deshacerte de esa entrada de carrito sin seguimiento y desconectada, debes adjuntarla a tu contexto de datos (haciendo que se rastree) y luego marcarla para eliminar al enviarla. En el momento en que envíe sus cambios, la entrada del carrito se eliminará correctamente y no causará la excepción.

Para obtener más detalles sobre este tema, consulte esto: http://msdn.microsoft.com/en-us/library/bb546187%28v=VS.100%29.aspx


Parece que estás buscando algo que buscaba yo solo hace unos días cuando pregunté " ¿Cómo diseño tipos de datos de respaldo para un cuadro de diálogo WPF de datos con los botones Aceptar / Cancelar? ".

La respuesta es una publicación intrigante de Paul Stovell que describe un adaptador IEditable de muestra para Linq a Sql. Esto le permitirá crear su semántica deseada "Aplicar / Cancelar" de una manera general sin disociarse por completo de las clases subyacentes generadas por ORm a través de una capa completa personalizada.

En general, es un truco astuto que esencialmente te permitirá soslayar los problemas que estás enfrentando en este momento. :)

En una nota diferente, tengo curiosidad por saber por qué tu relación de receta a ingrediente es 1: n en lugar de m: n. ¿Es por simplicidad? Uso ajo en muchas recetas. :)