编辑数据库上下文以从相关实体获取名称

Edit db context to get name from related entity

我是 VS2019、EF 和 .net Core 3.1 的新手,所以请多多包涵。

数据库上下文

        modelBuilder.Entity<Books>(entity =>
        {
            entity.Property(e => e.Id).HasColumnName("id");

            entity.Property(e => e.Createdon)
                .HasColumnName("createdon")
                .HasColumnType("datetime")
                .HasDefaultValueSql("(getdate())");

            entity.Property(e => e.Goal)
                .HasColumnName("goal")
                .HasMaxLength(100)
                .IsUnicode(false);

            entity.Property(e => e.Grade)
                .HasColumnName("grade")
                .HasMaxLength(2)
                .IsUnicode(false);

            entity.Property(e => e.Subjectid).HasColumnName("subjectid");

            entity.HasOne(d => d.Subject)
                .WithMany(p => p.Books)
                .HasForeignKey(d => d.Subjectid)
                .HasConstraintName("FK_Books_Subjects");
        });

        modelBuilder.Entity<Subjects>(entity =>
        {
            entity.Property(e => e.Id).HasColumnName("id");

            entity.Property(e => e.Createdby).HasColumnName("createdby");

            entity.Property(e => e.Name)
                .HasColumnName("name")
                .HasMaxLength(50)
                .IsUnicode(false);
        });

这里我想在检索图书时从主题实体中获取主题名称。 不幸的是,我没有可用的 EF Desginer 模型(不知道为什么)。 是否可以通过 dbcontext 执行此操作?

所以 Books 和 Subject 之间存在 one-to-many 关系:每一本书都有一个 Subject,即外键 SubjectId 所指的那个。每个主题都是零个或多个书籍的主题。

现在您需要书籍(的某些属性),每本书都有其主题名称,也许还有一些其他主题属性。

如果您的书 class 有 属性 virtual Subject Subject {get; set;},您可以使用 属性 来获取它。 Entity framework 知道 one-to-many 关系并知道如何将其转换为正确的 (Group-)Join。

如果 classes 没有这个 属性,你应该自己加入:

使用虚拟属性

class Subject
{
    public int Id {get; set;}
    ...

    // Every Subject is the subject of zero or more Books (one-to-many)
    public virtual ICollection<Book> Books {get; set;}
}
class Book
{
    public int Id {get; set;}
    ...

    // Every Book has exactly one Subject, using foreign key:
    public int SubjectId {get; set;}
    public virtual Subject Subject {get; set;}
}

这就是 entity framework 检测你们的 one-to-many 关系所需知道的全部内容。

var booksWithTheirSubjectNames = dbContext.Books

    // only if you don't want all Books
    .Where(book => ...)

    .Select(book => new
    {
        // Select the Book properties that you plan to use:
        Id = book.Id,
        Title = book.Title,
        ...

        // Select the subject properties that you plan to use
        Subject = new
        {
             Name = book.Subject.Name,
             Description = book.Subject.Description,
             ...
        },
    });

自己加入

如果你有一个 one-to-many 关系,你就有一个 one-side 和一个 many-side。要获取“具有零个或多个子项的项目”,请使用 GroupJoin,要获取“具有外键引用的唯一父项的项目”,请使用 Join.

var booksWithTheirSubjectNames = dbContext.Books.Join(dbContext.Subjects,

    book => book.SubjectId,     // from every Book take the foreign key
    subject => subject.Id,      // from every Subject take the primary key

    // when they match, take the Book and the Subject to make one new object:
    (book, subject) => new
    {
        Id = book.Id,
        Title = book.Title,
        ...

        Subject = new
        {
             Name = book.Subject.Name,
             Description = book.Subject.Description,
             ...
        },
    });