entity-framework - tributarios - vocabulario en ingles de contaduria
Muchas a muchas relaciones no ahorran (1)
Se espera que no pase nada.
Lo que desea cambiar o agregar es una relación entre las entidades Service
y ServiceItem
. Pero no puede manipular las relaciones configurando el estado de una entidad en Modified
. Esto solo actualiza las propiedades escalares y complejas pero no las propiedades de navegación (= relaciones). (Por ejemplo, establecer el estado de una entidad de Service
en Modified
marcará Service.Title
y Service.Description
, etc. como modificado y garantizará que esas propiedades se guarden en la base de datos. Pero no le importa el contenido de Service.ServiceItems
.)
La única excepción en la que puede cambiar una relación al establecer el estado en Modified
son las Asociaciones de clave externa . Estas son asociaciones que tienen propiedades de clave externa expuestas en su entidad modelo y solo pueden ocurrir para asociaciones de uno a muchos o de uno a uno. Las relaciones de muchos a muchos son siempre asociaciones independientes, lo que significa que nunca pueden tener una propiedad de clave extranjera en una entidad. (Debido a que los FK están en la tabla de unión, pero la tabla de unión no es una entidad y está "oculta" de sus clases modelo).
Existe una forma de manipular directamente las relaciones para una asociación de muchos a muchos, pero requiere ir al ObjectContext
y su RelationshipManager
que es, en mi opinión, bastante avanzado y complicado.
La forma habitual y directa de agregar y eliminar entradas de relaciones a / de una asociación de muchos a muchos es simplemente agregando elementos y eliminando elementos de las colecciones mientras las entidades están vinculadas al contexto. El mecanismo de seguimiento de cambios de EF reconocerá los cambios que haya realizado y generará las declaraciones INSERT, UPDATE y DELETE apropiadas cuando llame a SaveChanges
.
El procedimiento exacto depende de si también desea guardar Service
y / o ServiceItem
como entidades nuevas o si solo desea agregar relaciones entre entidades existentes. Aquí están algunos ejemplos:
service
debe INSERTAR, todos losserviceItem
deben INSERTAR y las relaciones entre las entidades se deben INSERTAR también en la tabla de unión:using (var context = new MyContext()) { var service = new Service(); var serviceItem1 = new ServiceItem(); var serviceItem2 = new ServiceItem(); service.ServiceItems.Add(serviceItem1); service.ServiceItems.Add(serviceItem2); context.Services.Add(service); context.SaveChanges(); }
Agregar el servicio "raíz" del gráfico de objetos es suficiente porque EF reconocerá que todas las demás entidades en el gráfico no están vinculadas al contexto y asumirá que deben insertarse en la base de datos.
service
ya existe y NO se debe INSERTAR, todos losserviceItem
deben INSERTAR y las relaciones entre las entidades se deben INSERTAR también en la tabla de unión:using (var context = new MyContext()) { var service = new Service { ServiceID = 15 }; context.Services.Attach(service); var serviceItem1 = new ServiceItem(); var serviceItem2 = new ServiceItem(); service.ServiceItems.Add(serviceItem1); service.ServiceItems.Add(serviceItem2); context.SaveChanges(); }
EF reconoce aquí (cuando se llama a
SaveChanges
) que elservice
está conectado pero las otras entidades no lo están. No se produce INSERT para elservice
peroserviceItem1/2
se insertará junto con las entradas de la relación.service
ya existe y NO se debe INSERTAR, todos losserviceItem
ya existen y NO se deben INSERTAR, pero las relaciones entre las entidades se deben INSERTAR en la tabla de unión:using (var context = new MyContext()) { var service = new Service { ServiceID = 15 }; context.Services.Attach(service); var serviceItem1 = new ServiceItem { ServiceItemID = 23 }; context.ServiceItems.Attach(serviceItem1); var serviceItem2 = new ServiceItem { ServiceItemID = 37 }; context.ServiceItems.Attach(serviceItem2); service.ServiceItems.Add(serviceItem1); service.ServiceItems.Add(serviceItem2); context.SaveChanges(); }
Para completar: ¿Cómo eliminar las relaciones entre las entidades existentes?
using (var context = new MyContext()) { var service = context.Services .Include(s => s.ServiceItems) // load the existing Items .Single(s => s.ServiceID == 15); var serviceItem1 = service.ServiceItems .Single(s => s.ServiceItemID == 23); // query in memory, no DB query var serviceItem2 = service.ServiceItems .Single(s => s.ServiceItemID == 37); // query in memory, no DB query service.ServiceItems.Remove(serviceItem1); service.ServiceItems.Remove(serviceItem2); context.SaveChanges(); }
Las dos filas de relaciones en la tabla de unión que vinculan el servicio 15 con serviceItem 23 y 37 se eliminarán.
Alternativamente, en lugar de llamar Attach
, puede cargar las entidades existentes desde la base de datos. Funcionará también:
var service = context.Services.Single(s => s.ServiceID == 15);
Y lo mismo para los ServiceItem
s existentes.
Tengo dos entidades con una relación de muchos a muchos bastante estándar que creé en el Código EF 5 primero. Estos son Service y ServiceItem. La entidad de servicio contiene una colección de artículos de servicio y el artículo de servicio contiene una colección de servicios. Puedo crear, cambiar y guardar datos en cualquiera de las propiedades básicas de las entidades sin problemas. Cuando intento agregar un artículo de servicio a un servicio o un servicio a un artículo de servicio parece funcionar, pero no se guarda nada. He verificado que se crean todas las tablas de base de datos adecuadas, incluida una tabla ServiceItemService con las claves cruzadas. La tabla de base de datos ServiceItemService no obtiene ninguna entrada cuando agrego los elementos. No hay error y todo lo demás parece funcionar perfectamente.
Estoy un poco perplejo y podría necesitar algo de ayuda. A continuación se presentan las clases.
La clase de servicio;
public class Service
{
//Default constructor
public Service()
{
//Defaults
IsActive = true;
ServicePeriod = ServicePeriodType.Monthly;
ServicePeriodDays = 0;
ServiceItems = new Collection<ServiceItem>();
}
public int ServiceID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public ICollection<ServiceItem> ServiceItems { get; set; }
public string TermsOfService { get; set; }
public ServicePeriodType ServicePeriod { get; set; }
public int ServicePeriodDays { get; set; }
public bool IsActive { get; set; }
}
La clase ServiceItem;
public class ServiceItem
{
public ServiceItem()
{
IsActive = true;
}
public int ServiceItemID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public ICollection<Service> Services { get; set; }
public string UserRole { get; set; }
public bool IsActive { get; set; }
}
Esta es la asignación de Fluido que hice al intentar depurar este problema. El mismo problema ocurrió antes y después de agregar este mapeo.
public DbSet<Service> Services { get; set; }
public DbSet<ServiceItem> ServiceItems { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Service>()
.HasMany(p => p.ServiceItems)
.WithMany(r => r.Services)
.Map(mc =>
{
mc.MapLeftKey("ServiceItemID");
mc.MapRightKey("ServiceID");
mc.ToTable("ServiceItemService");
});
}
Aquí está el código que utilizo para guardar el elemento de Servicio que incluye 2-3 Artículos de Servicio en la colección Servicio.Servicios de Servicio. He verificado cuidadosamente que los ServiceItems estaban en la colección adecuada.
db.Entry(dbService).State = EntityState.Modified;
db.SaveChanges();
El objeto dbService no parece verse afectado de ninguna manera. Los ServiceItems aún se encuentran en la colección adecuada, pero no se realizan actualizaciones a la tabla de base de datos ServiceItemService. Cualquier consejo sería muy bienvenido.
-Gracias