ОК, во-первых, вам нужно исправить вашу объектную модель, так как она дает вам неверную схему БД в том виде, в каком она сейчас стоит. Если вы посмотрите на полученную схему, вы увидите, что EF создал дополнительный InvestmentId (с именем Investment_InvestmentId) для tblPerformance. Все, что вам нужно сделать, это указать, что ваша связь между классами Investment и Performance, представленными в свойствах Investment.Performances и Performance.Investment, является двунаправленной.
Если вы предпочитаете аннотации данных по сравнению с текущими API (как это выглядит), вам нужно использовать атрибут InverseProperty , например:
[Table("tblPerformance")]
class Performance
{
[Key]
public string PerformanceId { get; set; }
public string InvestmentId { get; set; }
[InverseProperty("Performances")]
public virtual Investment Investment { get; set; }
}
Теперь исключение, которое вы получаете, очень нормально. Подумайте об этом, вы просите EF добавить два объекта для вас в одной транзакции: объект инвестиций, у которого есть основной объект производительности, поэтому EF сначала пытается вставить запись производительности, чтобы получить PrimaryPerformanceId для объекта инвестиций (с InvestmentId = 1), но затем он отмечает, что для записи эффективности также необходим тот же объект Инвестиции (с Id = 1), что и для его Инвестиции. Какой из них пойдет первым? Невозможно в одной транзакции.
Поэтому единственный способ заставить его работать - это использовать две транзакции для добавления ваших объектов:
using(Context db = new Context())
{
var inv = db.Investments.Add(new Investment() { InvestmentId = "1"});
db.SaveChanges();
inv.PrimaryPerformance = new Performance()
{
PerformanceId = "A",
InvestmentId = "1"
};
db.SaveChanges();
}
И этот код работает просто отлично.
Примечание. Я использовал последнюю версию EF для запуска этого кода (v4.3.1). Поэтому, пожалуйста, обновите ваши двоичные файлы, если вы этого еще не сделали.