Отношения «многие ко многим» с таблицами поиска

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

    [ManyToMany(typeof(PersonColor), CascadeOperations = CascadeOperation.All)]
    public List<Color> FavoriteColors { get; set; } 
}

public class Color {
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    public string Name { get; set; }

    [ManyToMany(typeof(PersonColor))]
    public List<Person> People { get; set; }
}

public class PersonColor {
    [ForeignKey(typeof(Person))]
    public int PersonId { get; set; }

    [ForeignKey(typeof(Color))]
    public int ColorId { get; set; }
}

...

var person = new Person() {
    FirstName = "Adrian",
    LastName = "Simbulan",
    FavoriteColors = new List<Color>() {
        new Color() {Name = "Red"},
        new Color() {Name = "Green"}
    }
};

await _db.InsertWithChildrenAsync(person);

Итак, я пытаюсь установить отношения «многие ко многим» между «Человек» и «Цвет». Таблица цветов будет предварительно заполнена статическими данными.

Теперь проблема в том, что всякий раз, когда я выполняю команду «InsertWithChildrenAsync», она всегда вставляет новые данные в таблицу поиска цветов. Есть ли способ вставить запись человека с выбранными цветами, не затрагивая таблицу цветов?


person ad0ran    schedule 27.04.2015    source источник


Ответы (1)


Попробуйте удалить операцию каскадной записи из атрибута FavoriteColors:

[ManyToMany(typeof(PersonColor), CascadeOperations = CascadeOperation.CascadeRead)]
public List<Color> FavoriteColors { get; set; }

Таким образом, библиотека не будет выполнять рекурсивные операции записи в этой таблице.


Другим способом без изменения отношения является выполнение двухэтапной операции. Сначала вставьте объект, а затем обновите отношение:

await _db.InsertAsync(person);
await _db.UpdateWithChildrenAsync(person);

В обоих случаях объекты из списка FavoriteColors уже должны существовать в базе данных и должны иметь назначенный действительный первичный ключ. В соответствии с этим ваш пример кода никогда не будет работать, потому что идентификатор 0 во всех Color объектах.

person redent84    schedule 28.04.2015
comment
Изменение CascadeOperations на просто чтение сработало. Будет ли выполнение двухэтапной операции более стандартной практикой при вставке новых записей в таблицу, имеющую связь с таблицей поиска? - person ad0ran; 28.04.2015
comment
Двухэтапная операция — это то, что библиотека делает внутри. Второе решение просто не требует от вас изменения определения модели, если вам требуются рекурсивные операции записи в другом месте. Если в этом нет необходимости, придерживайтесь первого решения, чтобы избежать записи объектов Color по ошибке. - person redent84; 28.04.2015