2016-07-03 3 views
0

우리는 라이센스 번호를 발행하고 고객이 매년 업그레이드 할 수있는 제품을 판매합니다. LicenseUpgradedToUpgradedFrom 탐색 속성을 정의하여이 업그레이드 정보를 추적하는 POCO를 설정하여 관련 라이센스의 "체인"을 쉽게 위/아래로 이동할 수 있습니다. 그래서 기본적으로 다음과 같은 것 :다중 자체 참조 탐색 속성

public class License 
{ 
    [Key] 
    public string LicenseNum { get; set; } 
    // Other properties relating to license omitted... 

    // Optional relationship. 
    public License UpgradedTo { get; set; } 

    // Optional relationship. 
    public License UpgradedFrom { get; set; } 
} 

나는 이것을 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

이 시나리오는 의존성이 작동하는 방식 때문에 매우 까다로운 작업입니다.

트릭은 하나 이상의 추가 "가짜"속성을 추가하여 작업을 만드는 것입니다.

이 클래스는 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