【问题标题】:How to join two tables using Entity Framework and match foreign keys如何使用实体框架连接两个表并匹配外键
【发布时间】:2021-05-02 14:23:29
【问题描述】:

我是 C# 和实体框架的新手,所以我真的很困惑 - 对此深表歉意。

我目前有一个包含两个表的数据库,ArtistsAlbums

我想在一个页面上显示所有专辑的列表,并将相应的ArtistIDArtist 页面上的外键)链接到它。

我正在尝试将这两个表连接在一起,以便在我的 AllAlbums 页面上呈现它们。

有人可以看看我的代码并指出正确的方向吗?

目前我的页面只渲染出所有专辑,与艺人没有关系。

我将发布我目前拥有的相应代码 sn-ps。

AllAlbum.cshtml.cs

public class AllAlbumModel : PageModel
{
    DatabaseContext _Context;

    public AllAlbumModel(DatabaseContext databasecontext)
    {
        _Context = databasecontext;
    }

    public List<Album> AlbumList { get; set; }

    public void OnGet()
    {
        var data = (from albumlist in _Context.albums
                    select albumlist).ToList();

        AlbumList = data;
    }
}

专辑.cs

[Table("albums")]
public class Album
{
    [Key]
    public int AlbumId {get; set;}
    // [Required(ErrorMessage = "Enter Album ID")]
    public string Title {get; set;}
    // [Required(ErrorMessage = "Enter Title")]
    public int ArtistId {get; set;}
}

艺术家.cs

[Table("artists")]
public class Artist
{
    [Key]
    public int ArtistId {get; set;}
    // [Required(ErrorMessage = "Enter Album ID")]
    public string Name {get; set;}
    // [Required(ErrorMessage = "Enter Title")]
}

DatabaseContext.cs

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

    public DbSet<Album> albums { get; set; }
    public DbSet<Artist> artists { get; set; }
}

AllAlbum.cshtml

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayName("AlbumId")
            </th>
            <th>
                @Html.DisplayName("Title")
            </th>
            <th>
                @Html.DisplayName("ArtistId")
            </th>
            <th>Edit | Delete</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.AlbumList)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.AlbumId)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Title)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ArtistId)
                </td>
                <td>
                    <a asp-page="./AllAlbum" asp-route-id="@item.AlbumId">Edit</a> |
                    <a asp-page="./AllAlbum" onclick="return confirm('Are you sure you want to delete this album record?');" asp-page-handler="Delete" asp-route-id="@item.AlbumId">Delete</a>
                </td>
            </tr>
        }
    </tbody>

【问题讨论】:

标签: c# entity-framework entity-framework-core


【解决方案1】:

Entity Framework 应该知道Album 类上的ArtistIdArtist 表的外键。那么生成数据的查询可能是:

var albumList = _Context.albums.Include(x => x.artists).ToList();

使用.Include() 将生成一个连接表的查询。对于更详细的查询,您可以像这样生成自己的查询:

var albumsAndArtists = (from albumList in _Context.albums
                       join artistList in _Context.artists
                       on artistList.ArtistId 
                       equals albumList.ArtistId
                       select new 
                       {
                           Album = albumList,
                           Artist = artistList
                       })
                       .ToList();

要将第一个查询与.Include() 一起使用,您需要添加:

public virtual Artist artists { get; set; }

Album 类中。这将启用延迟加载并允许使用.Include()

【讨论】:

  • 使用此查询时,VSCode 将第 3 行和第 4 行的artistList 和albumList 下划线标记为错误,将鼠标悬停在上面,显示“名称'artistList' 不在'equals' 左侧的范围内. 考虑交换'equals'两边的表达式。”使用 dotnet run 也会出现此错误
  • 那么你应该交换它们。而不是artistList.ArtistId equals albumList.ArtistId 尝试albumList.ArtistId equals artistLIst.ArtistId。让我知道是否可以解决问题。
  • 还要使用Include,您可能需要命名空间语句using System.Data.Entity
【解决方案2】:

在你的专辑类中添加一个链接到艺术家的外键:

[ForeignKey("ArtistId")] 
public virtual Artist Artist {get; set;}

然后包括您获取数据的艺术家:

var data = _Context.albums
.Include(x => x.Artist)
.ToList(); 

然后您可以在您的 cshtml 中使用艺术家数据,例如 item.Artist...

【讨论】:

  • 你能告诉我把第一个代码块放在哪里吗?对不起,我是菜鸟。我将它与其他链接一起放在我的 Artist.cs 文件中,但出现错误?
  • 把它放在你发布的代码最后一行之后的相册类中
  • 刚添加进去,添加第二个块后,'Include'带有红色下划线,消息“'DbSet'不包含'Include'的定义并且没有可访问的扩展方法'包括'接受类型为'DbSet'"的第一个参数
猜你喜欢
  • 2017-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多