2015-09-09 16 views
36

Ich habe folgende Einheiten in meinem DbContext:Conditional-Mapping mit graphdiff

enter image description here

public class A 
{ 
    public A() 
    { 
     Bs = new List<B>(); 
    } 

    public ICollection<B> Bs { set; get; } 
} 

Manchmal möchte ich a Diagramm aktualisieren:

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); 

Ich möchte a mit seinen Bs aktualisieren (Aktualisierung C, , E auch) mit graphdiff:

dbContext.UpdateGraph(a,map=>map.OwnedCollection(x=>x.Bs)); 

Das aktualisiert A, B s, C s, D s, aber nicht E s.

Also ich denke, ich brauche eine bedingte Zuordnung für graphdiff, zu definieren, zu aktualisieren E s, Somethings wie:

dbContext.UpdateGraph(a,map=>map.OwnedCollection(x=>x.Bs.OfType<D>(), 
              with =>with.OwnedCollection(t=>t.Es)) 
           .OwnedCollection(x=>x.Bs.OfType<C>())); 

Gibt es eine Möglichkeit, diese Arbeit zu tun?

+0

Haben Sie im dbContext angegeben, dass d die Sammlung Es 'besitzt'? etwas wie dbContext.UpdateGraph (d, map => map.OwnedCollection (x => x.Es)); ? –

+0

@PaulZahra: Ja – Masoud

Antwort

1

diese Weise können Sie mit graphdiff:

dbContext.UpdateGraph(a, map => map 
    .OwnedCollection(b => p.Bs, with => with 
    .AssociatedCollection(p => p.Es))); 

siehe diesen Link: GraphDiff Explanation

0

Ich glaube nicht, dass möglich ist, Ihre aktuelle Klassenstruktur verwenden. Allerdings habe ich einen Weg gefunden, dies zu erreichen, aber Sie müssen einige Änderungen in Ihrem Code vornehmen.

Aktualisieren der 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; }  
} 

aktualisieren B, C und 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>(); 
    } 
} 

Um die TPH-Strategie, einige Zuordnungen sind notwendig zu halten.

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")); 

Jetzt haben Sie fast die gleiche Datenbankstruktur. C und sind immer noch auf die gleiche Tabelle abgebildet.

Schließlich aktualisieren Sie die Grafik:

context.UpdateGraph(a, map => map 
    .OwnedCollection(b => b.Cs) 
    .OwnedCollection(b => b.Ds, with => with 
     .AssociatedCollection(e => e.Es))); 

Hoffe, es hilft!