Dodawanie nowego obiektu z obiektami obcymi

0

Cześć,
na podstawie komentarzy pod moim ostatnim postem postanowiłem nauczyć się EntityFramework (i używania angielskich nazw też ;]). Od razu zaznaczam, że jestem doperio na samym początku nauki : )

Mam stworzone dwie proste klasy - Student i Grade:

public class Student
{
  public int Id { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public int GradeId { get; set; }
  public Grade Grade { get; set; }
}

public class Grade
{
  public int Id { get; set; }
  public string Name { get; set; }
  public IList<Student> Students { get; set; } = new List<Student>();
}

Jestem na etapie dodawania obiektów do bazy. Wiem, że

using (DbContext context ....){
  context.Grades.Add(grade);
}

Dodaje nowy Grade do tabeli.

I teraz mam pytanie odnośnie dodawania Studenta. Ma on utworzoną relację z Grade. Powiedzmy, że tak wygląda zawartość tabeli stopni:

Id Name
1 Pierwsza
2 Druga

Chcę dodać Studenta, który należy do klasy o ID = 2. Gdy używałem ADO.NET, odnosiłem się bezpośrednio do właściwości Grade:

cmd.Parameters.AddWithValue("@GradeId", student.Grade.Id);

Było to wygodne, bo Grade.Id bindowałem do ComboBoxa w WPFie.

Gdy jednak próbuję zrobić to samo w EfCore:

Student st = new Student()
{
  FirstName = "Zbigniew",
  LastName = "JSON",
  Grade = new Grade(2, string.Empty)
};

context.Students.Add(st);

Dostaję błąd

SqlException: Cannot insert explicit value for identity column in table 'Grades' when IDENTITY_INSERT is set to OFF.

Mój kod działa tylko gdy zamiast Grade = new (2, ...), ustawiam bezpośrednio właściwość GradeId = 2. Dlaczego EF dodaje do bazy stopień, jeśli podaję jego ID? Czy ustawianie GradeId to jedyne rozwiązanie i nie da się zmusić EF do pobierania wartości bezpośrednio z klasy?

PS: Nie mogę znaleźć w internecie żadnego przykładu, stąd pytanie.

2

Dzieje się tak ponieważ używanie new tworzy nowy obiekt przez co EF myśli, że chcesz dodać nowy stopień do bazy razem ze studentem.
Mozesz robić tak jak napisałeś, czyli student.GradeId = 2 albo wyciągnać najpierw Grade z bazy i go przypisać do studenta:

Grade g = context.Grades.First(x => x.Id == 2);
student.Grade = g;
0

Dzięki

1

BTW jeśli Grade to ocena studenta, to za moich czasów student mógł dostać więcej, niż jedną.

0
ŁF napisał(a):

BTW jeśli Grade to ocena studenta, to za moich czasów student mógł dostać więcej, niż jedną.

Oj tam, to jest po prostu system typu last write wins.

1 użytkowników online, w tym zalogowanych: 0, gości: 1