[英]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是包含來自A
和B
數據的“超類”。 如果是這樣,那么您只需將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匹配的列名。 默認值表示列名: AId
和BId
因為主鍵是一個對象,所以在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.