2015-09-24 65 views
3

在使用SQLite.Net.Async擴展PCL 1.3.0的實體中是否可以有多個OneToOne關係?與SQLite.Net.Async擴展PCL 1.3.0在同一對象上的多個@OneToOne?

例子:

[Table("body")] 
public class Body 
{ 
    [OneToOne(CascadeOperations = CascadeOperation.All)] 
    [Column ("left")] 
    public Hand Left { get; set; } 

    [OneToOne(CascadeOperations = CascadeOperation.All)] 
    [Column ("right")] 
    public Hand Right { get; set; } 
} 

[Table("hand")] 
public class Hand 
{ 
    // In this I do not need a reference back to Body. 
} 

我已經使用了以下的答案嘗試:

SQLite-Net Extension both one-to-one and one-to-many relationships between two entities

並與這些站點作爲靈感也:

https://bitbucket.org/twincoders/sqlite-net-extensions/overview

https://bitbucket.org/twincoders/sqlite-net-extensions/src/65a1f8519347c40c948855cfc1a1d4d8bbcc8748/Tests/ReflectionExtensionsTests.cs?at=master&fileviewer=file-view-default

不幸的是,目前還沒有運氣。它甚至有可能嗎?

回答

3

是的,這是完全可能的,不幸的是,您不能依靠自動外鍵和反向關係發現,所以您需要手動指定它。

例如,對於一個int主鍵和外鍵聲明如在同一個班級:

public class Body 
{ 
    [OneToOne(foreignKey: "LeftId", CascadeOperations = CascadeOperation.All)] 
    public Hand Left { get; set; } 

    [OneToOne(foreignKey: "RightId", CascadeOperations = CascadeOperation.All)] 
    public Hand Right { get; set; } 

    // Foreign key for Left.Id 
    public int LeftId { get; set; } 
    // Foreign key for Right.Id 
    public int RightId { get; set; } 
} 

public class Hand 
{ 
    [PrimaryKey, AutoIncrement] 
    public int Id { get; set; } 
} 

如果你的外鍵在Hand對象聲明的屬性的屬性是相同的:

public class Body 
{ 
    [PrimaryKey, AutoIncrement] 
    public int Id { get; set; } 

    [OneToOne(foreignKey: "LeftId", CascadeOperations = CascadeOperation.All)] 
    public Hand Left { get; set; } 

    [OneToOne(foreignKey: "RightId", CascadeOperations = CascadeOperation.All)] 
    public Hand Right { get; set; } 
} 

public class Hand 
{ 
    [PrimaryKey, AutoIncrement] 
    public int Id { get; set; } 

    // Foreign key for Body.Id where this object is Left 
    public int LeftId { get; set; } 
    // Foreign key for Body.Id where this object is Right 
    public int RightId { get; set; } 
} 

如果需要,反相屬性必須在OneToOne屬性的兩端的inverseProperty鍵中指定:

public class Body 
{ 
    // Skipping foreign keys and primary key 

    [OneToOne(foreignKey: "LeftId", inverseProperty: "LeftBody", CascadeOperations = CascadeOperation.All)] 
    public Hand Left { get; set; } 

    [OneToOne(foreignKey: "RightId", inverseProperty: "RightBody", CascadeOperations = CascadeOperation.All)] 
    public Hand Right { get; set; } 
} 

public class Hand 
{ 
    // Skipping foreign keys and primary key 

    [OneToOne(foreignKey: "LeftId", inverseProperty: "Left", CascadeOperations = CascadeOperation.All)] 
    public Body LeftBody { get; set; } 

    [OneToOne(foreignKey: "RightId", inverseProperty: "Right", CascadeOperations = CascadeOperation.All)] 
    public Body RightBody { get; set; } 
} 
+0

謝謝@ redent84,我終於用你的例子做了工作。這兩種方法在性能方面是否有所不同?也就是說,最好是將外鍵保存在身體還是手中?實際上我只需要身體知道兩隻手,並且我計劃遞歸地查詢它們,所以人們應該認爲將外鍵保存在Body中是優選的? - 一個額外的問題是什麼時候我應該查詢上述結構,然後在GetAllWithChildrenAsync中設置遞歸標誌。是否可以指定要獲取的對象或可能的深度,即獲取的深度? – dynamokaj

+0

性能方面通過主鍵訪問對象更好,所以如果要從'Body'遞歸訪問'Hands',最好將外鍵保留在'Body'中。在這種特殊情況下它也更有意義。至於遞歸,如果你不需要,可以將'CascadeOperations'更改爲更保守的東西。目前沒有辦法在運行時指定深度,它只基於關係屬性的'CascadeOperations'屬性。 – redent84

+0

「不幸的是,你不能依靠自動外鍵和反向關係發現」 - 就我個人而言,我更喜歡這一點,不僅僅是爲了性能,而是爲了減少猜測並依靠框架來嘗試假設基於字符串的事情! – Tor