#entity-framework #.net-core #foreign-keys
#entity-framework #.net-ядро #внешние ключи
Вопрос:
У меня есть две сущности, а именно Idea и Reaction
Тема:
public class Idea
{
public string Id { get; set; }
public string Description { get; set; }
public DateTime TimePosted { get; set; }
public ICollection<Reaction> Reactions { get; set; }
}
Реакция:
public class Reaction
{
public string Id { get; set; }
public string Text { get; set; }
public DateTime TimePosted { get; set; }
public Reaction Parent { get; set; }
}
База данных SQLite сгенерирована нормально, без необходимости вносить какие-либо изменения в OnModelCreating в моем DbContext, поскольку в моей реакции был столбец для IdeaId
и ParentId
. Но когда я хочу добавить свою реакцию на тему, FK, похоже, никогда не заполняется.
Вот как я пытаюсь его добавить:
public void AddIdeaReaction(string id, string reactionText)
{
Idea idea = _ideaRepo.GetById(id);
Reaction reaction = new Reaction()
{
Id = Guid.NewGuid().ToString(),
TimePosted = DateTime.Now,
Text = reactionText
};
_reactionRepo.Create(reaction);
idea.Reactions.Add(reaction);
UpdateIdea(idea);
}
Реакция добавляется в таблицу, но значение FK для IdeaId остается нулевым.
Что я делаю не так?
РЕДАКТИРОВАТЬ: Проблема заключалась в том, что я установил для автоматической отслеживания изменений значение false.
Ответ №1:
Вам нужно добавить IdeaId
в вашу Reaction
таблицу
public class Reaction
{
public string Id { get; set; }
public string Text { get; set; }
public DateTime TimePosted { get; set; }
public Reaction Parent { get; set; }
public int IdeaId { get; set; }
}
Таким образом, EF может определить, как связаны данные, когда вы создаете или обновляете сущность
Извините за мой английский.
Комментарии:
1. Но EF добавляет IdeaId в базу данных для меня? И я пробовал это в другом тестовом проекте только с этим сценарием, и там все работает нормально
2. Но EF добавляет IdeaId в базу данных для меня? —> Да, предполагается, что это делается в режиме fluent API, EF автоматически определяет взаимосвязи, не указывая их явно.
Ответ №2:
Вам все равно нужно сообщить EF об отношениях либо через OnModelCreating, либо через конфигурацию. EF может заполнить некоторые пробелы с помощью соглашения, но, честно говоря, я на это не рассчитываю и просто использую явные сопоставления, потому что тогда я уверен, что он связывает вещи так, как я ожидаю.
// ** EF6 **
public class IdeaConfiguration : EntityTypeConfiguration<Idea>
{
public IdeaConfiguration()
{
ToTable("Ideas");
HasKey(x => x.Id);
HasMany(x => x.Reactions)
.WithRequired()
.Map(x => x.MapKey("IdeaId")); // This tells EF to use an IdeaId field on Reaction.
}
}
// ** EF Core **
public class IdeaConfiguration : IEntityTypeConfiguration<Idea>
{
void IEntityTypeConfiguration<Idea>.Configure(EntityTypeBuilder<Idea> builder)
{
builder.ToTable("Ideas");
builder.HasKey(x => x.Id);
builder.HasMany(x => x.Reactions)
.WithOne()
.HasForeignKey("IdeaId"); // Creates a shadow property for the association.
}
}
Это также может быть возможно с атрибутами. Явная конфигурация IMO просто оставляет меньше загадок, чтобы тратить время. 🙂