如何建立一对一和多对一关系 EF?
How to have a one to one, and a many to one, relation ship EF?
上下文:
我正在使用 entity framework 核心代码优先方法。 entity framework 核心位于 .Net 核心 class 库中。
情况:
关系
我有一个名为 Question
的 table 和一个名为 AnswerOption
的 table。这些 table 具有如下关系:
- A
Question
有一个 AnswerOption
类型的 RightAnswer
- 一个
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; }
}
问题
创建数据库时抛出以下错误:
'Unable to determine the relationship represented by navigation
property 'AnswerOption.Question' of type 'Question'. Either manually
configure the relationship, or ignore this property using the
'[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in
'OnModelCreating'.'
我已经尝试在 DbContext OnModelCreating()
方法中手动设置关系船 entity framework relationship builder class 但不完全知道如何让这种关系发挥作用.
如何声明这些 table 之间的一对一和多对一关系?
以下是在 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();
}
}
}
上下文:
我正在使用 entity framework 核心代码优先方法。 entity framework 核心位于 .Net 核心 class 库中。
情况:
关系
我有一个名为 Question
的 table 和一个名为 AnswerOption
的 table。这些 table 具有如下关系:
- A
Question
有一个AnswerOption
类型的 RightAnswer
- 一个
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; }
}
问题
创建数据库时抛出以下错误:
'Unable to determine the relationship represented by navigation property 'AnswerOption.Question' of type 'Question'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.'
我已经尝试在 DbContext OnModelCreating()
方法中手动设置关系船 entity framework relationship builder class 但不完全知道如何让这种关系发挥作用.
如何声明这些 table 之间的一对一和多对一关系?
以下是在 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();
}
}
}