Несколько однозначных отношений с одной и той же таблицей

Каков наилучший способ моделирования нескольких отношений «один к одному» с одной и той же таблицей (sqlite-net-extensions)? Я ищу такое решение:

Class WayBill 
{
    [PrimaryKey, AutoIncrement]
    public int Id {get; set;} 

    [ForeignKey(typeof(Organization ))]
    public int ConsignerId {get; set;}

    [OneToOne]
    public Organization Consigner {get; set;}  

    [ForeignKey(typeof(Organization ))]
    public int ConsigneeId {get; set;}

    [OneToOne]
    public Organization Consignee {get; set;} 
}


Class Organization 
{
    [PrimaryKey, AutoIncrement]
    public int Id {get; set;} 

    public string Name {get; set;}
}    

Очевидно, что вышеописанное не сработает.

Я рассматривал и другие варианты:

  1. создайте таблицу (WayBillOrganization), отражающую роль организации: Накладная -->> WayBillOrganization --> Организация

  2. поместите необходимые обратные свойства OneToMany в организацию.

  3. Обрабатывайте вещи вручную (т.е. храните только первичные ключи в классе WayBill и загружайте организации отдельно).

Вариант 2. Это то, чего я хочу избежать. Организации связаны со многими другими классами (не в моем примере), и даже в случае с накладной есть еще несколько отношений, которые я не включил в пример (перевозчик, плательщик груза, экспедитор и т. д.). Кроме того, я бы предпочел использовать инверсные свойства только тогда, когда мне нужно перемещаться (например, я не использую организацию для поиска накладных, поэтому инверсное свойство — это только дополнительная нагрузка).

Вариант 3 тоже не так привлекателен.

Таким образом, вариант 1. кажется правильным. Но прежде чем идти туда, я хотел бы знать, действительно ли решение идеального мира в моем примере невозможно.

Итак, мой вопрос: есть ли способ смоделировать несколько однонаправленных отношений OneToOne без явно объявленных обратных свойств?


person user2261054    schedule 09.12.2015    source источник


Ответы (1)


Ваш вариант использования поддерживается в расширениях SQLite-Net. Вам нужно только явно указать внешние ключи в атрибутах отношения, потому что автоматическое обнаружение может работать не так, как ожидалось:

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

    public int ConsignerId {get; set;}

    [OneToOne("ConsignerId")]
    public Organization Consigner {get; set;}  

    public int ConsigneeId {get; set;}

    [OneToOne("ConsigneeId")]
    public Organization Consignee {get; set;} 
}


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

    public string Name {get; set;}
}

Обратные отношения к тому же классу также поддерживаются, но также должны быть явно объявлены на обоих концах:

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

    public int ConsignerId {get; set;}

    [OneToOne(foreignKey: "ConsignerId", inverseProperty: "ConsignerInverse")]
    public Organization Consigner {get; set;}  

    public int ConsigneeId {get; set;}

    [OneToOne(foreignKey: "ConsigneeId", inverseProperty: "ConsigneeInverse")]
    public Organization Consignee {get; set;} 
}


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

    public string Name {get; set;}

    [OneToOne(foreignKey: "ConsigneeId", inverseProperty: "Consignee")]
    public WayBill ConsigneeInverse { get; set; }

    [OneToOne(foreignKey: "ConsignerId", inverseProperty: "Consigner")]
    public WayBill ConsignerInverse { get; set; }
}
person redent84    schedule 09.12.2015
comment
Рад, что смог помочь. Если это решило вашу проблему, рассмотрите возможность голосования / пометки как принятого, чтобы другие люди могли его найти. - person redent84; 10.12.2015
comment
Спасибо за вклад (Y). Кстати, в приведенном выше сценарии предпочтительнее использовать таблицу соединений вместо прямого сопоставления. - person harshlal028; 29.01.2017