Изменение порядка вставки LINQ to SQL - PullRequest
3 голосов
/ 01 апреля 2009

У меня есть два класса LINQ to SQL, CandyBar и DeliciousCandyBar, которые сопоставляются с таблицами с одинаковыми именами в SQL Server.

Между CandyBar и DeliciousCandyBar существует связь 0..1. то есть CandyBar может иметь 0 или 1 DeliciousCandyBars. И наоборот, в DeliciousCandyBar есть ровно один CandyBar.

В классе LINQ to SQL они выглядят (в основном) как

class CandyBar {
  public int Id { get;set;} // this is primary key w/ autoincrement identity
  public string Name {get;set;}
  public EntityRef<DeliciousCandyBar> DeliciousCandyBar {get;set;}
}

class DeliciousCandyBar {
  public int DeliciousnessFactor {get;set;}
  public int CandyBarId {get;set;} // FK to candyBar Id
  public EntityRef<CandyBar> CandyBar {get;set;} // the association property of the FK
}

Чтобы заполнить базу данных (через l2sql), мой сканер выходит и находит конфеты и вкусные конфеты.

Но с первым восхитительным моноблоком, который мой сканер вставляет в CandyStoreDataContext, DataContext вызывает исключение при вызове SubmitChanges.

Сканер запускает следующий код для одного восхитительного моноблока. Обратите внимание, что это пример. Точный процесс является более сложным, и я использую специальный сканер DSL, который выплевывает эту структуру объекта. По сути, выполняется следующее.

var dc = CandyStoreDataContext();
var bar = new CandyBar() {
    Name = "Flake",
    DeliciousCandyBar = new DeliciousCandyBar() {
      DeliciousnessFactory = 12
    }
};

dc.CandyBars.InsertOnSubmit(bar);

dc.SubmitChanges();

В методе SubmitChanges () возникает исключение SqlException с сообщением «Оператор INSERT конфликтует с ограничением FOREIGN KEY FK_CandyBar_DeliciousCandyBar. Конфликт произошел в базе данных CandyStoreData, таблица« dbo.DeliciousCandyBar », столбец« CandyBarI ». 1015.

Проблема стала ясна, когда я сбросил CandyStoreDataContext.Log в Console.Out, сгенерированные операторы вставки были в неправильном направлении. LINQ to SQL пытался сначала вставить DeliciousCandyBar (который пытался установить недопустимое значение в столбце CandyBarId), а не вставлять CandyBar первым.

У меня вопрос: как заставить Linq to SQL поменяться местами с инструкциями вставки?

Я предполагал (неправильно), что LINQ to SQL будет знать направление зависимости отношений и будет делать это наоборот.

UPDATE:

Этот пост говорит о том, что я неправильно понимаю Ассоциацию. Но это не имеет смысла для меня. Это имеет смысл, когда моделируется в базе данных. Как это можно сделать наоборот.

В CandyBar атрибут ассоциации в свойстве DelciousCandyBar имеет вид [Association (Name = "DeliciousCandyBar_CandyBar", Storage = "_ DeliciousCandyBar", ThisKey = "Id", OtherKey = "CandyBarId", IsForeignKey = true)]

В DeliciousCandyBar атрибут ассоциации в свойстве CandyBar имеет вид [Association (Name = "DeliciousCandyBar_CandyBar", Storage = "_ CandyBar", ThisKey = "CandyBarId", OtherKey = "Id", IsUnique = true, IsForeignKey = false)]

Хорошо, теперь я запутался, почему второй атрибут помечен как внешний ключ.

Я собираюсь попытаться воссоздать эти отношения между CandyBar и DeliciousCandyBar в студии SQL Management

ОБНОВЛЕНИЕ 2

Хорошо, я пытался создать отношения в обоих направлениях. И SSMS действительно дает понять, где находится первичный ключ (CandyBar.Id). Я правильно понял с первого раза. В противном случае каскадное движение вернулось бы назад.

Ответы [ 2 ]

0 голосов
/ 01 апреля 2009

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

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

Как только вы подтвердите, что это не работает, и что при повторном добавлении их в конструктор они не устанавливаются правильно, откройте свойства рабочей ассоциации в конструкторе и убедитесь, что есть связь между моноблоком и восхитительной конфеткой настроен таким же образом.

0 голосов
/ 01 апреля 2009

Пожалуйста, попробуйте эту альтернативу:

  1. Вставьте экземпляр CandyBar без дочерних DeliciousCandyBar объектов, затем вызовите метод SubmitChanges().

  2. Предполагается, что у вас есть ID или GUID, связывающий два объекта - скажем, CandyBarID. Затем установите значение CandyBarID в экземпляре DeliciousCandyBar равным экземпляру CandyBar.

  3. После этого вы можете вставить объект DeliciousCandyBar, и, поскольку CandyBarID установлено, отношение должно быть правильным при выборе CandyBar объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...