c# - tools - entity framework save relationship
Mapeo condicional con graphdiff (2)
Tengo las siguientes entidades en mi DbContext
:
public class A
{
public A()
{
Bs = new List<B>();
}
public ICollection<B> Bs { set; get; }
}
A veces quiero actualizar a
gráfico:
var a = dbContext.As
.AsNoTracking()
.Include(x=>x.Bs)
.firstOrDefault();
var c = new C();
a.Bs.Add(c);
var d = new D();
var e1 = new E();
var e2 = new E();
d.Es.Add(e1); //<-- added new E
d.Es.Add(e2); //<-- added new E
a.Bs.Add(d);
Quiero actualizar a
con sus Bs
(actualizar C
, D
, E
también) usando graphdiff
:
dbContext.UpdateGraph(a,map=>map.OwnedCollection(x=>x.Bs));
Esto actualiza A
, B
s, C
s, D
s, pero no E
s.
Entonces, creo que necesito definir un mapeo condicional para graphdiff
, para actualizar E
s también, graphdiff
como:
dbContext.UpdateGraph(a,map=>map.OwnedCollection(x=>x.Bs.OfType<D>(),
with =>with.OwnedCollection(t=>t.Es))
.OwnedCollection(x=>x.Bs.OfType<C>()));
¿Hay alguna forma de hacer este trabajo?
No creo que eso sea posible usando tu estructura de clase actual. Sin embargo, encontré una manera de lograr esto, pero tienes que hacer algunos cambios en tu código.
Actualiza la A
:
public class A
{
public A()
{
Cs = new List<C>();
Ds = new List<D>();
}
//PK
public int AId { get; set; }
public ICollection<C> Cs { set; get; }
public ICollection<D> Ds { set; get; }
}
Actualización B
, C
y D
:
public class B
{
public int BId { get; set; }
}
public class C : B
{
//FK that links C to A
public int FK_C_AId { get; set; }
}
public class D : B
{
//FK that links D to A
public int FK_D_AId { get; set; }
public ICollection<E> Es { get; set; }
public D()
{
Es = new List<E>();
}
}
Para mantener la estrategia de TPH, algunas asignaciones son necesarias.
modelBuilder.Entity<A>()
.HasMany(i => i.Cs)
.WithRequired()
.HasForeignKey(i => i.FK_C_AId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<A>()
.HasMany(i => i.Ds)
.WithRequired()
.HasForeignKey(i => i.FK_D_AId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<B>()
.Map<C>(m => m.Requires("Discriminator").HasValue("C"))
.Map<D>(m => m.Requires("Discriminator").HasValue("D"));
Ahora, tienes casi la misma estructura de base de datos. C
y D
todavía están mapeados en la misma tabla.
Finalmente, actualice el Gráfico:
context.UpdateGraph(a, map => map
.OwnedCollection(b => b.Cs)
.OwnedCollection(b => b.Ds, with => with
.AssociatedCollection(e => e.Es)));
¡Espero eso ayude!
Puedes usar esto con graphdiff:
dbContext.UpdateGraph(a, map => map
.OwnedCollection(b => p.Bs, with => with
.AssociatedCollection(p => p.Es)));
ver este enlace: GraphDiff Explicación