我什么时候需要在EF的DbContext中指定DbSet?

时间:2018-01-24 21:44:18

标签: c# asp.net .net entity-framework dbcontext

我有点困惑。直到今天,我还认为必须在DbContext类中指定每个表(由EF使用)。但看起来我需要只有一个!真的?

让我解释一下,这是我的DbContext:

public class MyDbContext : DbContext
{
    public MyDbContext()
        : base("name=MyDbContext")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.SetInitializer<MyDbContext>(null);
        base.OnModelCreating(modelBuilder);
    }    

    public DbSet<Table1> Table1 { get; set; }
    public DbSet<Table2> Table2 { get; set; }
    public DbSet<Table3> Table3 { get; set; }
    public DbSet<Table4> Table4 { get; set; }
    public DbSet<Table5> Table5 { get; set; }
}

以下是两个示例表,连接1:很多

[Table("Table1")]
public class Table1
{
    [Key]
    [Column("Table1Id", TypeName = "uniqueidentifier")]
    public int Table1Id { get; set; }

    [Column("Table2Id", TypeName = "int")]
    public int Table2Id { get; set; }

    [ForeignKey("Table2Id")]
    public Table2 Table2 { get; set; }
}

[Table("Table2")]
public class Table2
{
    public Table2()
    {
        this.Table1s = new HashSet<Table1>();
    }

    [Key]
    [Column("Table2Id", TypeName = "int")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Table2Id { get; set; }

    public ICollection<Table1> Table1s { get; set; }
} 

易。现在,我想查询所有Table2s与相应的Table1s。我这样做:

var tables2 = fni.Set<Table2>()
    .Include(i => i.Table1s)
    .Where(t => t.Table2Id == 123456).ToList();

一切正常,但当我偶然发现它甚至可以使用这个DbContext时,我感到很震惊:

public class MyDbContext : DbContext
{
    public MyDbContext()
        : base("name=MyDbContext")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.SetInitializer<MyDbContext>(null);
        base.OnModelCreating(modelBuilder);
    }    


    public DbSet<Table1> Table1 { get; set; }
}

或者这个..

public class MyDbContext : DbContext
{
    public MyDbContext()
        : base("name=MyDbContext")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.SetInitializer<MyDbContext>(null);
        base.OnModelCreating(modelBuilder);
    }    


    public DbSet<Table2> Table2 { get; set; }
}

你能解释一下,为什么会这样?怎么样?

谢谢!

EDIT。它不包括在内。我能做到:

var tables2 = fni.Set<Table2>()
    .Where(t => t.Table2Id == 123456).ToList();

在DbContext中只有public DbSet<Table1> Table1 { get; set; }。它甚至不是Table2!它们通过FK连接(定义没有改变)。这意味着,您必须只有一个表“链”中的一个表。这是对的吗?

3 个答案:

答案 0 :(得分:4)

让我们看一下documentation

我们有以下型号:

public class Student
    {
        public int ID { get; set; }
        public string LastName { get; set; }
        public string FirstMidName { get; set; }
        public DateTime EnrollmentDate { get; set; }

        public ICollection<Enrollment> Enrollments { get; set; }
    }

public class Enrollment
    {
        public int EnrollmentID { get; set; }
        public int CourseID { get; set; }
        public int StudentID { get; set; }
        public Grade? Grade { get; set; }

        public Course Course { get; set; }
        public Student Student { get; set; }
    }

public class Course
    {
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int CourseID { get; set; }
        public string Title { get; set; }
        public int Credits { get; set; }

        public ICollection<Enrollment> Enrollments { get; set; }
    }

和DB上下文:

public class SchoolContext : DbContext
    {
        public SchoolContext(DbContextOptions<SchoolContext> options) : base(options)
        {
        }

        public DbSet<Course> Courses { get; set; }
        public DbSet<Enrollment> Enrollments { get; set; }
        public DbSet<Student> Students { get; set; }
    }

可是:

  

您可以省略DbSet<Enrollment>DbSet<Course>   声明,它将工作相同。实体框架会   隐式包含它们,因为Student实体引用了   注册实体和注册实体引用课程   实体。

<强> PS 即可。对不起,我刚刚注意到这个问题与EF Core无关。但无论如何,我认为它应该是真的。

答案 1 :(得分:0)

原因纯粹是出于讽刺。如果要直接使用DbContext并访问您的实体,请使用DbSet。。如果使用UnitOfWork / Repository模式将其抽象出来,则可能根本不需要dbSet。它们只是提供了一种简单的途径,可以通过DbContext访问您的实体

答案 2 :(得分:0)

经过一些测试,我发现您的上下文中至少需要一个DBSet与 您要创建的表。
换句话说,这就是您要创建的表所引用的表。 其次,您还需要在查找表中具有一个导航属性,该属性引用要创建的表。

例如,您有一个Student表。然后,您有一个注册表,可查找学生表。

因此,Students表必须至少是一个DBSet。在学生班上,您必须有一个 导航到注册的属性,如:

public ICollection<Enrollment> Enrollments {get;set;}

这样,EntityFramework,找到Student DBSet,然后转到Student模型并找到Enrollment导航属性并创建表。