EntityFramework Core 2.2 до 3.1.1 Ошибка - PullRequest
2 голосов
/ 29 января 2020

Я только что закончил обновление моего. net core 2.2 до 3.1.101. Когда я запускаю (do tnet run), я получаю эту ошибку на своих контроллерах

Невозможно определить представленное отношение по свойству навигации «UserAssignment.Appointee» типа «Пользователь». Либо настройте отношение вручную, либо игнорируйте это свойство с помощью атрибута «[NotMapped]» или с помощью «EntityTypeBuilder.Ignore» в «OnModelCreating».

Позвольте мне сначала объяснить отношение, пользователь может иметь много UserAssignment, каждое UserAssignment может иметь Appointee и Manager (который является другим пользователем).

UserAssignment

namespace CRSApp.API.Models
{
    public class UserAssignment
    {
        public int UserId { get; set; }
        public User User { get; set; }
        public DateTime StartDate {get; set;}
        public bool IsPersonalInsolvency { get; set; }
        public bool IsCorporateInsolvency { get; set; }
        public int? AppointeeId { get; set; }
        public User Appointee { get; set; }
        public int? ManagerId { get; set; }
        public User Manager { get; set; }
        public int? StaffDefaultRateId {get; set;}
        public StaffDefaultRate StaffDefaultRate { get; set; }
    }
}

User.cs

public class User
        {
            public int Id { get; set; }
            [Column(TypeName = "varchar(200)")]
            public string Username { get; set; }
            [Column(TypeName = "blob")]
            public byte[] PasswordHash { get; set; }
            [Column(TypeName = "blob")]
            public byte[] PasswordSalt { get; set; }
            [Column(TypeName = "varchar(200)")]
            public string FirstName { get; set; }

            [Column(TypeName = "varchar(200)")]
            public string LastName { get; set; }

            [Column(TypeName = "varchar(200)")]
            public string MiddleName { get; set; }

            [Column(TypeName = "varchar(200)")]
            public string Email { get; set; }       
            public string MobileNumber { get; set; }       

            public ICollection<UserAssignment> Assignments {get; set;}

        }

построитель модели DbContext :

    builder.Entity<UserAssignment>().HasKey(x => new {x.UserId, x.StaffDefaultRateId});
    builder.Entity<UserAssignment>()
        .HasOne( x => x.User)
        .WithMany(y => y.Assignments)
        .HasForeignKey( x => x.UserId);
    builder.Entity<UserAssignment>()
        .HasOne( x => x.StaffDefaultRate)
        .WithMany( y => y.Assignments)
        .HasForeignKey( x => x.StaffDefaultRateId);

Пожалуйста, помогите мне, как решить эту проблему? как и в предыдущем ef core 2.2, этот код работает нормально.

Ответы [ 2 ]

2 голосов
/ 29 января 2020

Очевидно, что ошибка (что-то было сломано при исправлении чего-то другого).

Похоже, что наличие двух неявно сопоставленных ссылочных навигационных свойств для User (Manager и Appointee) сбивает с толку EF Core 3.1 Обычное отображение отношений.

Добавление

builder.Entity<UserAssignment>()
    .HasOne(x => x.Appointee);

или

builder.Entity<UserAssignment>()
    .HasOne(x => x.Manager);

исправит это, но во избежание таких проблем в будущем, я бы предложил явно отобразить, по крайней мере, навигационные свойства предполагаемого отношения:

builder.Entity<UserAssignment>()
    .HasOne(x => x.Appointee)
    .WithMany();
builder.Entity<UserAssignment>()
    .HasOne(x => x.Manager)
    .WithMany();
2 голосов
/ 29 января 2020

https://docs.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key#conventions

Согласно соглашениям, ваш код правильный.

https://github.com/dotnet/efcore/issues/13274#issuecomment -420322267

Соглашение используется только для объектов в контексте. Добавить DbSet<UserAssignment> в вашем контексте может работать.

Или вы можете указать внешний ключ:

builder.Entity<UserAssignment>()
    .HasOne( x => x.Appointee)
    .HasForeignKey( x => x.AppointeeId);
builder.Entity<UserAssignment>()
    .HasOne( x => x.Manager)
    .HasForeignKey( x => x.ManagerId);
...