簡體   English   中英

少林一對一關系

[英]One-to-one relation in Shaolinq

我正在使用Shaolinq庫進行數據庫使用,並且一對一關系存在問題。 我有以下數據庫架構:

create table A (
    Id INT NOT NULL,
    PRIMARY KEY (`Id`)
);
create  table B (
    Id INT NOT NULL,
    PRIMARY KEY (`Id`),
    CONSTRAINT `fk_a_b_id` FOREIGN KEY (`Id`) REFERENCES `A` (`Id`)
);

基本上,這兩個表包含有關相同內容的信息,只是不同的數據。 那是有人設計的方式,我無法更改。

但是,在代碼中,我希望將所有這些數據放在一個對象中。 我一直在嘗試BackReference,但沒有運氣:

[DataAccessObject]
public abstract class A : DataAccessObject<uint>
{
    [AutoIncrement]
    [PersistedMember]
    public abstract uint Id { get; set; }

    [RelatedDataAccessObjects]
    public abstract RelatedDataAccessObjects<B> Bs { get; }
}

[DataAccessObject]
public abstract class B : DataAccessObject
{
    [BackReference(Name = "", PrefixName = "", SuffixName = "")]
    public abstract A Id { get; set; }

    [PersistedMember]
    public abstract string MoreData { get; set; }
}

這創建了某種相似的模式(顯然B中的Id現在不是主鍵),但是在我將數據填充到DB中之后,A中的Bs屬性未填充引用。 簡單地將類型B的抽象屬性放在A中似乎也不起作用,因為同一列同時是外鍵和主鍵(Id)。

歡迎任何建議。

您是否需要從As訪問B的集合? 在我看來,B是包含來自AB數據的“超類”。 如果是這樣,那么您只需將A作為B的主鍵即可。

[DataAccessObject]
public abstract class A : DataAccessObject<uint>
{
    [PersistedMember(Name = "Id")]
    public abstract override uint Id { get; set; }

    [PersistedMember]
    public abstract string Data { get; set; }
}

[DataAccessObject]
public abstract class B : DataAccessObject<A>
{
    [PersistedMember(Name = "Id", PrefixName = "")]
    public abstract override A Id { get; set; }

    [PersistedMember]
    public abstract string MoreData { get; set; }
}

請注意,我已重寫Id屬性以獲取與SQL匹配的列名。 默認值表示列名: AIdBId

因為主鍵是一個對象,所以在Shaolinq術語中將其稱為“復雜主鍵”。 您可以使用放氣的引用功能來檢索對象,而只需將它們作為它們的主鍵即可,而無需往返數據庫(更多信息: https : //github.com/tumtumtum/Shaolinq/wiki/Deflated-References

您可以查詢B的特定值:

// Need to define primary key using an anonymous object because it's not an uint but rather an A that contains an uint.
model.Bs.GetByPrimaryKey(new { Id = 100 } );

您還可以使用放氣的引用查詢B的特定值:

model.Bs.GetByPrimaryKey(model.As.GetReference(100));

您還可以在普通的LINQ查詢中使用引用:

model.Bs.Where(c => c.Id == model.As.GetReference(100) || c.Id == model.As.GetReference(101)).ToList();

您也可以直接在查詢中訪問嵌套/復雜的主鍵:

model.Bs.Where(c => c.Id.Id == 100 || c.Id.Id == 101).ToList();

請注意,由於復雜的主鍵被展平並存儲在表B上,因此上述三個查詢不需要執行隱式聯接。

當你回到B ,你可以訪問B.Id.Id不用往返查詢,但如果你訪問B.Id.Data那么這將導致B.Id到自動隱藏往返到數據庫膨脹 為避免這種情況,您可以使用Include在第一個查詢中自動為B.Id充氣。

model.Bs.Include(c => c.Id).Single(c => c.Id == model.As.GetReference(100));

或更簡潔地說:

model.Bs.Include(c => c.Id).Single(c => c.Id.Id == 100);

暫無
暫無

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

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