2016-07-03 15 views
0

私たちはライセンス番号を発行する製品を販売しており、お客様は毎年アップグレードすることができます。 LicenseUpgradedToUpgradedFromナビゲーションプロパティを定義することで、このアップグレード情報を追跡するPOCOをセットアップして、関連するライセンスの「チェーン」を簡単に上下に移動できます。したがって、基本的には次のようなものです:複数の自己参照ナビゲーションプロパティ

私は実際にEF AnnotationsとFluent APIでこれを定義する方法を苦労しています。私は自己参照面が私を踏みつけていると思っています。

また、設定のいずれかギブLicense上でこれらのUpgradeTo/UpgradeFrom特性の一つとEFは関係のもう一方の端に「反対」アップグレード財産の世話を持ってできるようにしたいと思います。したがって、次のようなものがあります。

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

答えて

0

このシナリオは、依存関係がどのように機能しているかによって非常に難しいです。

このトリックは、ジョブを作成するために1つ以上の追加の「偽の」プロパティを追加することです。

このクラスは、UpgradeTo値を設定した場合、UpgradedFromプロパティを自動的に設定します。

例:このアプローチは完璧に動作

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

エンティティ

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

コンテキスト

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

。これは本当にありがとう! – John