ASP.NET

Moje problemy z kluczami obcymi w podejściu code-first w aplikacji ASP.NET

Moja aplikacja na Daj Się Poznać powoli się rozwija. Wraz z tym ciągłym rozwojem musiałem dokonać modyfikacji struktury bazy danych. Do tabeli zadań konieczne było dodanie kolumny z ID użytkownika, któremu zlecamy zadanie (będzie kluczem obcym tabeli użytkowników). Istnieje już podobne powiązanie tych samych tabel – dla użytkownika tworzącego zadanie. Dodam jeszcze, że korzystam z możliwości code-first w Entity Framework.
Zmodyfikowałem więc szybko model „Zadania”. Początkowo miałem tylko jedno powiązanie:

[MaxLength(128)]
[ForeignKey("UserID")]
public string TaskOwnerId { get; set; }

public virtual ApplicationUser UserID { get; set; }

Dostawiłem drugie:

[MaxLength(128)]
[ForeignKey("UserID")]
public string TaskOwnerId { get; set; }

[MaxLength(128)]
[ForeignKey("UserID")]
public string TaskExecutorId { get; set; }

public virtual ApplicationUser UserID { get; set; }

Przystąpiłem to przygotowania migracji za pomocą konsoli NuGet:

PM> Add-Migration Task

Pudło! Otrzymałem taki komunikat:

Unable to determine a composite foreign key ordering for foreign key on type todo.team.Domain.Entities.Task. When using the ForeignKey data annotation on composite foreign key properties ensure order is specified by using the Column data annotation or the fluent API.

Szybki research i gotowe. Po drobnej modyfikacji mojej encji migracja przeszła poprawnie…

[MaxLength(128)]
[ForeignKey("OwnerUserID")]
public string TaskOwnerId { get; set; }

[MaxLength(128)]
[ForeignKey("ExecutorUserID")]
public string TaskExecutorId { get; set; }

public virtual ApplicationUser OwnerUserID { get; set; }
public virtual ApplicationUser ExecutorUserID { get; set; }

…, a baza została zaktualizowana za pomocą automatycznie wygenerowanego kodu.

CreateTable(
    "dbo.Tasks",
    c => new
        {
            TaskOwnerId = c.String(maxLength: 128),
            TaskExecutorId = c.String(maxLength: 128),
            TaskId = c.Int(nullable: false, identity: true),
            TaskSubject = c.String(nullable: false, maxLength: 128),
            TaskBody = c.String(),
            TaskCreateDate = c.DateTime(nullable: false),
            TaskStartDate = c.DateTime(),
            TaskEndDate = c.DateTime(),
            TaskScheduleTypeId = c.Int(),
            TaskStatusId = c.Int(),
        })
    .PrimaryKey(t => t.TaskId)
    .ForeignKey("dbo.AspNetUsers", t => t.TaskExecutorId)
    .ForeignKey("dbo.AspNetUsers", t => t.TaskOwnerId)
    .Index(t => t.TaskOwnerId)
    .Index(t => t.TaskExecutorId);

Nie za bardzo rozumiałem wcześniej tworzenie relacji między tabelami w podejściu code-first, stąd ta pomyłka. Wklejam rozwiązanie, gdyby ktoś miał kiedyś podobny przypadek. Więcej o tworzeniu bazy na podstawie modelu aplikacji w nadchodzącym wpisie na blogu.

Stay tuned! 

Tagi:asp.netcode-firstDaj Się Poznać 2017entity framework

Brak komentarzy

Napisz komentarz jako pierwszy!

Zostaw odpowiedź