#c# #asp.net-core #entity-framework-core
Вопрос:
У меня есть ASP.NET Приложение MVC, которое использует Entity Framework с навигацией на основе соглашений, и оно отлично работает. Я решил поэкспериментировать, переехав в ASP.NET Ядро 5 с ядром Entity Framework v5.0.6. Ну не просто, какой медведь, так как соглашения для одного ко многим нарушаются. Боюсь попробовать мои многие-ко-многим!
Я расширил IdentityUser
, чтобы включить свойство навигации List<BookedDates>
:
public class ApplicationUser : IdentityUser
{
public int skillLevel { get; set; }
public int timesCaptain { get; set; }
public int bFreezeDB { get; set; }
public string memberName { get; set; }
public virtual List<BookedDates> bookedDates { get; set; }
public virtual List<Match> Matches { get; set; }
public ApplicationUser()
{
bFreezeDB = 0;
}
}
Теперь у пользователя может быть много BookDates
:
public class BookedDates
{
public int id { get; set; }
public int month { get; set; }
public virtual ApplicationUser user { get; set; }
public string status { get; set; }
}
Первоначальный миграционный код выглядит хорошо, так как, похоже, он подобрал отношения с внешними ключами:
migrationBuilder.CreateTable(
name: "statusforDays",
columns: table => new
{
id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(type: "nvarchar(max)", nullable: true),
month = table.Column<int>(type: "int", nullable: false),
status = table.Column<string>(type: "nvarchar(max)", nullable: true),
ApplicationUserId = table.Column<string>(type: "nvarchar(450)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_statusforDays", x => x.id);
table.ForeignKey(
name: "FK_statusforDays_AspNetUsers_ApplicationUserId",
column: x => x.ApplicationUserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
Затем в своем контроллере я делаю следующий вызов:
ApplicationUser user = _db.Users
.Include(u => u.bookedDates)
.Where(u => u.Email == email)
.SingleOrDefault();
Я получаю эту ошибку:
«Microsoft.Data.SqlClient.SQLException» в Microsoft.EntityFrameworkCore.Relational.dll
В Microsoft произошло исключение типа «Microsoft.Data.SqlClient.SQLException».EntityFrameworkCore.Реляционный.dll, но не был обработан в коде пользователя
Недопустимое имя столбца «Идентификатор пользователя».
Откуда это userid
берется? Я знаю, что, вероятно, смогу использовать Fluent и создать связь, но я думал, что EF Core 5 должен был обрабатывать простую навигацию на основе соглашений намного лучше, чем v3
Ответ №1:
Я всегда предлагаю подход FluentAPI, потому что это дает вам больше контроля над отношениями.
В вашем BookedDates
классе у вас есть свойство навигации: public virtual ApplicationUser user { get; set; }
. По соглашению, EF Core выполняет поиск по имени свойства, за которым следует Id
столбец внешнего ключа: userId
как показано в ошибке.
Переименуйте свойство как public virtual ApplicationUser ApplicationUser { get; set; }
, и вместо этого соглашение будет искать ApplicationUserId
поле в таблице userId
.
Комментарии:
1. Затем отметьте ответ как решение, пожалуйста. Кто-то проголосовал против ответа без комментариев по причине.