簡體   English   中英

我何時需要在EF的DbContext中指定DbSet?

[英]When do I need to specify DbSet in EF's 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; }
} 

簡單。 現在,我想查詢具有相應Table1的所有Table2。 我做:

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; }
}

您能告訴我,為什么行得通? 怎么樣?

謝謝!

編輯。 不包括在內。 我能夠做到:

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

只有這樣: public DbSet<Table1> Table1 { get; set; } public DbSet<Table1> Table1 { get; set; } public DbSet<Table1> Table1 { get; set; } 甚至沒有Table2! 它們通過FK連接(定義未更改)。 因此,這意味着您只能在一個“表鏈”中只有一個表。 那是對的嗎?

讓我們看一下文檔

我們有以下模型:

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; }
    }

和數據庫上下文:

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>語句,它的工作原理相同。 實體框架將隱式包括它們,因為學生實體引用了注冊實體,而注冊實體引用了課程實體。

PS 抱歉,我只是注意到了有關EF Core的問題。 但我認為無論如何應該如此。

原因純粹是共謀。 如果要直接使用DbContext並訪問您的實體,請使用DbSet。。如果使用UnitOfWork / Repository模式將其抽象出來,則可能根本不需要dbSet。 它們只是提供一種通過DbContext訪問您的實體的簡便方法

經過一些測試,我發現您的上下文中至少需要一個DBSet與要創建的表相關。
換句話說,這就是您要創建的表所引用的表。 其次,您還需要在查找表中具有一個導航屬性,該屬性引用要創建的表。

例如,您有一個Student表。 然后,您有一個注冊表,它查找學生表。

因此,Students表必須至少是一個DBSet。 在“學生”類中,您必須具有“注冊”的導航屬性,例如:

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

這樣,EntityFramework,找到Student DBSet,然后轉到Student模型並找到Enrollment導航屬性並創建表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM