У меня есть два класса 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). Я правильно понял с первого раза. В противном случае каскадное движение вернулось бы назад.