簡體   English   中英

多個自引用導航屬性

[英]Multiple self-referencing naviation properties

我們出售一種產品,我們為其頒發許可證號,並且客戶可以每年進行升級。 我想設置一個License POCO,它通過定義UpgradedToUpgradedFrom導航屬性來跟蹤此升級信息,這將使我們能夠輕松地上下移動相關許可證的“鏈”。 所以基本上是這樣的:

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注釋和Fluent API來定義它。 我認為自我參照的方面是讓我絆倒的。

我們還希望能夠在給定License上設置這些UpgradeTo / UpgradeFrom屬性之一,並讓EF負責關系另一端的“相反” Upgrade屬性。 因此,如下所示:

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

這種情況非常棘手,因為依賴性是如何工作的。

訣竅是添加一個或多個其他“偽”屬性來完成這項工作。

如果您設置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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM