0

我正在浏览来自 www.ASP.net 网站的 Mvc 音乐商店教程。

我无法理解 Entity Framework 如何创建表以及这些 lambda 表达式是如何工作的。我确实了解 EF 和 Lambda 的基础知识,并且我已经完成了本系列之前的教程。

我的问题与教程的第 4 部分有关:第 4 部分:模型和数据访问模型 中有三个类:艺术家、流派和专辑,如下所示。

public class Artist
{
    public int ArtistId { get; set; }
    public string Name { get; set; }
}
public partial class Genre
{
    public int      GenreId     { get; set; }
    public string   Name        { get; set; }
    public string   Description { get; set; }
    public List<Album> Albums   { get; set; }
}
public class Album
{
    public int      AlbumId     { get; set;}
    public int      GenreId     { get; set; }
    public int      ArtistId    { get; set; }
    public string   Title       { get; set; }
    public decimal  Price       { get; set; }
    public string   AlbumArtUrl { get; set; }
    public Genre    Genre       { get; set; }
    public Artist   Artist      { get; set; }
}

但是,我只看到 EF 创建的每个表的以下列。

艺术家表:ArtistId, Name

流派表:GenreId, Name, Description

专辑表:AlbumId, GenreId, ArtistId, Title, Price, AlbumArtUrl

混乱一

Artist 表很好,但 Genre 表与类定义无关List<Album> Albums。在专辑表中public Genre Genre并且public Artist Artist丢失。

下面是在 SampleData.cs 文件中将默认数据添加到数据库的语句

new Album 
{ 
    Title = "A Copland Celebration, Vol. I", 
    Genre = genres.Single(g => g.Name == "Classical"), 
    Price = 8.99M, 
    Artist = artists
        .Single(a => a.Name == "Aaron Copland & London Symphony Orchestra"), 
    AlbumArtUrl = "/Content/Images/placeholder.gif" 
}

问题

现在数据库表中没有任何名称为 Genre 和 Artist 的字段??GenreId 和 ArtistId 未插入,但数据库中的专辑表填充了这些值。???

混淆二

在 StoreController 的 Browse 动作方法中,

// Retrieve Genre and its Associated Albums from database
var genreModel = storeDB.Genres.Include("Albums").Single(g => g.Name == genre);

我不知道 include 在这里是如何工作的。Genres 模型类中有 List of Albums 字段,但在数据库中没有。我猜想 include() 可能会在那里保存专辑列表。

问题

但我不明白为什么 Include 方法有“Albums”参数?有两个专辑列表,一个在 Genre 模型类中,另一个在派生自DbContextEF 的类中。此语句将如何仅返回具有匹配流派的专辑?

任何帮助表示赞赏。谢谢

4

1 回答 1

2

Artist 表很好,但 Genre 表没有关于类定义中的 List Albums 的信息。在专辑表中,公共类型流派和公共艺术家艺术家缺失。

现在数据库表中没有任何名称为 Genre 和 Artist 的字段??GenreId 和 ArtistId 未插入,但数据库中的专辑表填充了这些值。

您不必直接访问外键属性(ArtistID 和 GenreID),因为它们是通过 EF 导航属性为您处理的。您所要做的就是设置艺术家和/或流派,而 EF 会为您处理其余的事情。

和属性是导航属性GenreArtist它们实际上并未存储在数据库中,它是您访问相关流派实体和相关Artist实体的一种方式Album,或者访问与您的流派相关的所有专辑的一种方式。

例如,当您访问实体Artist上的属性时Album- EF 所做的是它将Artist在您的专辑中列出 ArtistID 的表中为您提供信息。

例如 - 你有一个 AlbumA - 它有一个 GenreA 和一个 ArtistA。它不是将所有信息存储在一个表中,而是将信息分解为单独的表,以便更好地存储和重用。现在您已经在代码中获取了 AlbumA - 但您想访问关联的 GenreA 的名称。你会使用:

AlbumA.Genre.Name

这将转到您的专辑表 - 获取 GenreId,然后转到您的流派表,并返回带有该 ID 的流派,然后给您 name 属性。这省去了您必须为已有的专辑编写通过 id 获取流派的函数的麻烦,从而为您提供更易于阅读的代码。

但我不明白为什么 Include 方法有“Albums”参数?有两个专辑列表,一个在 Genre 模型类中,另一个在从 DbContext for EF 派生的类中。此语句将如何仅返回具有匹配流派的专辑?

Include函数的作用是急切地加载您的实体。有关这方面的好信息,请参阅此博客文章。

当您加载流派对象时,它只加载流派表上的信息。当您想要访问关联的专辑时 - EF 必须进行额外的数据库调用。有时出于性能原因这确实很糟糕,因此 include 允许您进行连接,并在一次调用中检索所有关联的数据,而不是多次访问数据库。

关于什么是导航属性以及它们如何工作的一些额外资源:

  1. 什么是导航属性
  2. 导航属性入门
于 2013-03-03T19:57:22.847 回答