上下文
我正在使用实体框架核心代码的第一种方法。实体框架核心位于.Net核心类库中。
情况:
关系
我有一个名为Question
的表和一个名为AnswerOption
的表。这些表具有如下关系:
Question
有一个RightAnswer,类型为AnswerOption
Question
可以有更多AnswerOptions
一个问题有多个答案选项,其中一个是正确的答案。
代码
public class Question
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public virtual AnswerOption RightAnswerId { get; set; }
public virtual AnswerOption RightAnswer { get; set; }
public virtual ICollection<AnswerOption> AnswerOptions { get; set; }
}
public class AnswerOption
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int QuestionId { get; set; }
public virtual Question Question { get; set; }
}
问题
创建数据库时,会抛出以下错误:
&#39;无法确定导航所代表的关系 property&#39; AnswerOption.Question&#39;类型&#39;问题&#39;。手动 配置关系,或使用。忽略此属性 &#39; [NotMapped]&#39;属性或使用&#39; EntityTypeBuilder.Ignore&#39;在 &#39; OnModelCreating&#39;&#39;
我已尝试在DbContext类的OnModelCreating()
方法中手动设置关联版本entity framework relationship builder,但不完全知道如何使此关系起作用。< / p>
如何在这些表之间声明一对一和多对一关系?
答案 0 :(得分:1)
以下是在EF Core中如何做到这一点。 AnswerOption应该有一个复合键来提高性能,因此您可以强制确定问题的RightAnswer必须是该问题的AnswerOptions之一,这需要EF Core中的流畅配置。否则你只需要注释ForeignKey和InverseProperty,并使RightAnswerId可以为空,这样你就可以插入一个没有RightAnswer的问题。
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
//using Microsoft.Samples.EFLogging;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
namespace EFCore2Test
{
public class Question
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public virtual int? RightAnswerId { get; set; }
[ForeignKey("Id,RightAnswerId")]
public virtual AnswerOption RightAnswer { get; set; }
public virtual ICollection<AnswerOption> AnswerOptions { get; set; }
}
public class AnswerOption
{
public int QuestionId { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[InverseProperty("AnswerOptions")]
public virtual Question Question { get; set; }
}
public class Db : DbContext
{
public DbSet<Question> Questions { get; set; }
public DbSet<AnswerOption> AnswerOptions { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AnswerOption>().HasKey(e => new { e.QuestionId, e.Id });
base.OnModelCreating(modelBuilder);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=(local);Database=Test2;Trusted_Connection=True;MultipleActiveResultSets=true");
base.OnConfiguring(optionsBuilder);
}
}
class Program
{
static void Main(string[] args)
{
using (var db = new Db())
{
db.Database.EnsureDeleted();
// db.ConfigureLogging(s => Console.WriteLine(s));
db.Database.EnsureCreated();
for (int i = 0; i < 100; i++)
{
var q = new Question();
db.Questions.Add(q);
var a = new AnswerOption();
a.Question = q;
var b = new AnswerOption();
b.Question = q;
db.SaveChanges();
q.RightAnswer = a;
db.SaveChanges();
}
}
Console.WriteLine("Hit any key to exit");
Console.ReadKey();
}
}
}