Отношение многих ко многим SQLite: возможно ли это?


Я использую SQLite.net и SQLite-Net Extensions. Я хотел бы создать самоотношение «многие ко многим».
В моем случае у меня есть дочерний класс с некоторыми братьями и сестрами, конечно, братья и сестры по-прежнему относятся к дочернему типу. Поэтому я попытался реализовать отношение многие-многие:

Дочерний класс

[ManyToMany(typeof(Brotherhood), CascadeOperations = CascadeOperation.All)]
public List<Child> Siblings_DB { get; set; }

Класс братства

class Brotherhood
{
    [ForeignKey(typeof(Child))]
    public int ID_child1 { get; set; }

    [ForeignKey(typeof(Child))]
    public int ID_child2 { get; set; }

}

На этом и должна быть вся работа.
Затем я создаю Child и добавляю его в список Siblings, но когда я пытаюсь сохранить класс в базе данных с помощью InsertOrReplaceWithChildren(Child,true), обновляется только ID_child1, а ID_child2 остается равным 0.
Любая идея? Что я делаю не так?
Алекс


person Alex Gimondi    schedule 17.02.2017    source источник
comment
тот же вопрос здесь ... проверьте следующее: stackoverflow.com/questions/14227468/   -  person Mike Darwish    schedule 17.02.2017


Ответы (3)


Схема базы данных сначала должна быть совместима с тем, что вы пытаетесь сделать. Одна сторона отношения каждого должна быть ключевым (уникальным) атрибутом или набором атрибутов, поэтому у вас не может быть отношения «многие-ко-многим» само по себе. Но если вы создадите другую таблицу для хранения связанных строк с комбинированным ключом, который содержит две копии ключевого атрибута [s] из одной таблицы, для которой вы пытаетесь создать отношение, тогда вы сможете это сделать.

скажем, ключ таблицы - myPK, затем создайте вторую таблицу с именем, скажем myM2M с первичным ключом из двух столбцов, содержащим атрибуты myPK1 и myPK2, которые вместе образуют pk этой новой таблицы, затем сформируйте связь между обоими этими столбцами с myPK столбец в первой таблице.

Вы смотрели это?

person Charles Bretana    schedule 17.02.2017
comment
Моя цель - использовать ORM для создания этой связи, а не необработанный язык SQLite. Все работает, если отношение многие ко многим выполняется между двумя разными классами. Кроме того, я уже создал вторую таблицу: братство, которое должно осознавать отношение многих ко многим. Что-то не так, когда я использую один и тот же класс. Я посмотрю на пример спасибо - person Alex Gimondi; 17.02.2017

После некоторых попыток мне удалось осознать самоотношение многие ко многим, я был немного сбит с толку из-за наличия двух отношений многие-многие в одном и том же классе: мне было интересно, какое из них было «официальным». В конце концов я понял, что оба были! И сумма братьев и сестер была суммой двух списков.

[ManyToMany(typeof(Brotherhood), "ChildID1", "Siblings_DB_support", CascadeOperations = CascadeOperation.All)]
public List<Child> Siblings_DB { get; set; }
[ManyToMany(typeof(Brotherhood), "ChildID2", "Siblings_DB", CascadeOperations = CascadeOperation.All)]
public List<Child> Siblings_DB_support { get; set; }

И таблица отношений:

public class Brotherhood
{
    [ForeignKey(typeof(Child))]
    public int ChildID1 { get; set; }

    [ForeignKey(typeof(Child))]
    public int ChildID2 { get; set; }
}
person Alex Gimondi    schedule 20.02.2017

В этом сценарии вы должны явно указать внешние ключи и обратные отношения в атрибуте свойства.

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

    public string Name { get; set; }

    [ManyToMany(typeof(FollowerLeaderRelationshipTable), "LeaderId", "Followers",
        CascadeOperations = CascadeOperation.All)]
    public List<TwitterUser> FollowingUsers { get; set; }

    // ReadOnly is required because we're not specifying the followers manually, but want to obtain them from database
    [ManyToMany(typeof(FollowerLeaderRelationshipTable), "FollowerId", "FollowingUsers",
        CascadeOperations = CascadeOperation.CascadeRead, ReadOnly = true)]
    public List<TwitterUser> Followers { get; set; }
}

// Intermediate class, not used directly anywhere in the code, only in ManyToMany attributes and table creation
public class FollowerLeaderRelationshipTable {
    public int LeaderId { get; set; }
    public int FollowerId { get; set; }
}

Если ваши отношения - «брат-брат», а не «родители-дети», вам придется суммировать оба отношения, например:

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

    public string Name { get; set; }

    [ManyToMany(typeof(BrothersRelationshipTable), "OldBrotherId", "YoungerBrothers",
        CascadeOperations = CascadeOperation.All)]
    public List<Person> OlderBrothers { get; set; }

    [ManyToMany(typeof(BrothersRelationshipTable), "YoungBrotherId", "OlderBrothers",
        CascadeOperations = CascadeOperation.CascadeRead, ReadOnly = true)]
    public List<Brothers> YoungerBrothers { get; set; }

    [Ignore]
    publc List<TwitterUser> Brothers { 
        get { return YoungerBrothers.Concat(OlderBrothers).ToList() }
    }
}

// Intermediate class, not used directly anywhere in the code, only in ManyToMany attributes and table creation
public class BrothersRelationshipTable {
    public int OldBrotherId { get; set; }
    public int YoungBrotherId { get; set; }
}
person redent84    schedule 24.02.2017