2016-07-03 10 views
0

Wir verkaufen ein Produkt, für das wir Lizenznummern vergeben und das der Kunde jährlich aufrüsten kann. Ich möchte ein License POCO einrichten, das diese Upgrade-Informationen verfolgt, indem es die Navigationseigenschaften UpgradedTo und UpgradedFrom definiert, die es uns ermöglichen würden, die "Kette" verwandter Lizenzen leicht nach oben oder unten zu verschieben. Also im Grunde etwas wie die folgenden:Mehrere selbstreferenzierende Navigationseigenschaften

Ich bin wirklich Schwierigkeiten, wie dies mit EF Annotations und Fluent API zu definieren. Ich denke, dass der selbstreferenzierende Aspekt mich stolpert.

Wir würden auch am anderen Ende der Beziehung zu setzen eine dieser UpgradeTo/UpgradeFrom Eigenschaften auf einem give License und haben EF kümmern sich um die „gegenüber“ Upgrade Eigenschaft gerne in der Lage sein. So etwas wie das Folgende:

// Licenses upgraded 1 > 2 > 3 
License lic1 = CreateLicense('1'); 
License lic2 = CreateLicense('2'); 
License lic3 = CreateLicense('3'); 

using (var db = new Model1()) 
{ 
    // Insert into database 
    db.Licenses.Add(lic1); 
    db.Licenses.Add(lic2); 
    db.Licenses.Add(lic3); 
    db.SaveChanges(); 

    // Specify UpgradeFrom/UpgradeTo info only on lic2. 
    lic2.UpgradedFrom = lic1; 
    lic2.UpgradedTo = lic3; 
    db.SaveChanges(); 

    // lic1 and lic3 automatically update possible? 
    Debug.Assert(lic1.UpgradedTo == lic2); 
    Debug.Assert(lic3.UpgradedFrom == lic2); 
} 

Antwort

0

Dieses Szenario ist sehr schwierig, weil wie Abhängigkeit funktioniert.

Der Trick besteht darin, eine oder mehrere zusätzliche "falsche" Eigenschaften hinzuzufügen, um den Job zu machen.

Diese Klasse wird automatisch die UpgratedFrom-Eigenschaft festlegen, wenn Sie einen UpgradeTo-Wert festlegen.

Beispiel:

using (var ctx = new TestContext2()) 
{ 
    var license1 = ctx.Licenses.Add(new License() { LicenseNum = "1.0.0"}); 
    ctx.SaveChanges(); 

    var license2 = license1.UpgradeTo = new License() { LicenseNum = "1.0.2"}; 
    ctx.SaveChanges(); 

    var license3 = license2.UpgradeTo = new License() { LicenseNum = "1.0.3" }; 
    ctx.SaveChanges(); 
} 

Entities

public class License 
{ 
    [Key] 
    public string LicenseNum { get; set; } 

    private License _upgradeTo; 
    private License _upgradedFrom; 


    public License UpgradeTo 
    { 
     get { return _upgradeTo; } 
     set 
     { 
      _upgradeTo = value; 
      if (_upgradeTo != null && _upgradeTo.UpgradedFrom != this) 
      { 
       _upgradeTo.UpgradedFrom = this; 
      } 
     } 
    } 

    public License UpgradedFrom 
    { 
     get { return _upgradedFrom; } 
     set 
     { 
      _upgradedFrom = value; 
      if (_upgradedFrom != null && _upgradedFrom.UpgradeTo != this) 
      { 
       _upgradedFrom.UpgradeTo = this; 
      } 
     } 
    } 

    internal License InternalUpgradedTo 
    { 
     get { return UpgradeTo; } 
    } 

    internal License InternalUpgradedFrom 
    { 
     get { return UpgradedFrom; } 
    } 
} 

Kontext

public class TestContext2 : DbContext 
{ 
    public TestContext2() : base(My.Config.ConnectionStrings.TestDatabase) 
    { 

    } 
    public DbSet<License> Licenses { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<License>() 
      .HasOptional(v => v.UpgradeTo) 
      .WithOptionalDependent(x => x.InternalUpgradedFrom); 

     modelBuilder.Entity<License>() 
      .HasOptional(v => v.UpgradedFrom) 
      .WithOptionalDependent(x => x.InternalUpgradedTo); 
    } 
} 
+0

Dieser Ansatz funktioniert perfekt. Vielen Dank dafür! – John

Verwandte Themen