【问题标题】:Using data from a table and foreign key table in single query在单个查询中使用表和外键表中的数据
【发布时间】:2018-03-03 23:14:31
【问题描述】:

很难从标题中解释,希望这个描述有助于解释情况。我有一个音乐应用程序,用户可以在其中创建播放列表。所以我设置了两张桌子。

一个名为Playlists(列:PlaylistID、PlaylistName、CreatorID),另一个名为PlaylistSongs(列:PlaylistSongID、PlaylistID 和SongID)。我在 PlaylistID 列之间有一个外键连接。

我想在主页上显示一个播放列表列表,每个列表如下所示:

我可以从Playlist 表中提取播放列表名称并正确显示....简单。我遇到的问题是如何显示元数据,例如艺术家(Sasha Sloan ODESZA 等),我可以从通过外键连接的 PlaylistSongs 表中的 SongID 获取这些元数据。

这是我现在拥有的:

控制器

public ActionResult Playlists()
{
    var model = new HomePlaylistViewModel();
    model.Playlists = EntityDataAccess.GetFeaturedPlaylistsByCount(6);

    return View(model);
}

型号:

public class HomePlaylistViewModel
{
    public List<Playlist> Playlists { get; set; }
    public List<PlaylistSong> PlaylistSongs { get; set; }
    public List<Album> Albums { get; set; }
}

CSHTML:

<div class="playlists-container">

            @foreach (var item in Model.Playlists)
            {
                <div class="playlist-album">
                    <div class="album-grad"></div>
                    <a href="#">
                        <h1>
                            @item.PlaylistName
                        </h1>

                        <div class="playlist-desc-container">
                                <h4 class="playlist-desc">Featuring: INSERT ARTIST NAMES HERE</h4>
                                <h4 class="playlist-creator"> Songs &#8226; Curated by
                           </h4>
                        </div>

                        <img src="https://ucarecdn.com/6d669906-60df-4f26-bf80-f11eef3bd019/-/format/jpeg/-/quality/lightest/" class="playlist-album-art">
                    </a>
                    <button class="ui button playlist-listen">LISTEN</button>
                    <button class="ui button playlist-collect"><i class="material-icons">playlist_add</i></button>
                </div>
            }

播放列表.cs

public partial class Playlist
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Playlist()
    {
        this.PlaylistSongs = new HashSet<PlaylistSong>();
    }

    public int PlaylistID { get; set; }
    public string PlaylistName { get; set; }
    public int CreatorID { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<PlaylistSong> PlaylistSongs { get; set; }
}

EntityDataAccess.cs

public static List<Playlist> GetFeaturedPlaylistsByCount(int count)
        {
            using (var Context = GetContext())
            {
                return Context.Playlists.Take(count).ToList();
            }
        }

所以我基本上有一个带有 Playlist 信息的模型:

  • 播放列表 ID
  • 播放列表名称
  • 创作者 ID

我需要使用每个唯一的PlaylistID 来访问PlaylistSongs 表中具有PlaylistID 的歌曲,以便我可以在屏幕上显示。这有意义吗?

编辑:添加了对上下文和相应类的调用

public static UnearthEntities GetContext()
        {
            var context = new UnearthEntities();
            context.Configuration.ProxyCreationEnabled = false;
            return context;
        }

挖掘实体:

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

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }

        public virtual DbSet<AccountInfo> AccountInfoes { get; set; }
        public virtual DbSet<Album> Albums { get; set; }
        public virtual DbSet<AlbumTag> AlbumTags { get; set; }
        public virtual DbSet<AspNetRole> AspNetRoles { get; set; }
        public virtual DbSet<AspNetUserClaim> AspNetUserClaims { get; set; }
        public virtual DbSet<AspNetUserLogin> AspNetUserLogins { get; set; }
        public virtual DbSet<AspNetUser> AspNetUsers { get; set; }
        public virtual DbSet<DownloadHistory> DownloadHistories { get; set; }
        public virtual DbSet<Song> Songs { get; set; }
        public virtual DbSet<Spotlight> Spotlights { get; set; }
        public virtual DbSet<Video> Videos { get; set; }
        public virtual DbSet<FeaturedAlbum> FeaturedAlbums { get; set; }
        public virtual DbSet<Key> Keys { get; set; }
        public virtual DbSet<SongPlayDaily> SongPlayDailies { get; set; }
        public virtual DbSet<Favorite> Favorites { get; set; }
        public virtual DbSet<License> Licenses { get; set; }
        public virtual DbSet<Product> Products { get; set; }
        public virtual DbSet<Playlist> Playlists { get; set; }
        public virtual DbSet<PlaylistSong> PlaylistSongs { get; set; }
    }

【问题讨论】:

    标签: c# asp.net entity-framework


    【解决方案1】:

    参考微软文章:Entity Framework Loading Related Entities

    假设您的数据上下文是正确的,请使用Include 引入相关数据,例如:

    return Context.Playlists.Include("PlaylistSongs").Take(count).ToList();
    

    顺便说一句:为清楚起见,我会重命名您的一些字段。例如,主键 (PK) 字段名称不需要以表名称作为前缀。它变得混乱。只需将您的 PK 字段命名为“Id”。从相关表中引用关键字段时,请使用表名。例如,要在 Playlists 和 PlaylistSongs 之间建立一对多的关系,PlaylistSongs 表中将存在一个名为 PlaylistId 的字段。

    关于模型的构建,请看微软的文档Creating a ModelForeign Key Constraints。第一个提供了指向示例代码的 github repo 的链接。

    【讨论】:

    • 感谢您迄今为止的帮助。今天我一直在努力解决同一篇文章。我已经多次添加和删除了Include。这次出于好奇(添加了它),我去了我的 html 并添加了 @item.PlaylistSongs.Count 以查看它是否甚至在读取值并且我的 html 是空白的。这是否意味着我的数据上下文搞砸了?
    • 发布您的数据上下文。您调用了 GetContext(),让我们看看负责返回 this 的代码。
    • 添加了对原始问题的编辑,这是您想要检查的吗?
    • 我已更新答案以包含其他讨论如何定义/创建模型的文章。
    • 我相信是的。如果您想要一个决定性的解决方案,请将您的解决方案上传到 github 并使用指向 repo 的链接更新您的答案。然后我们可以去克隆它并看看。这是复制您的环境的唯一方法。该解决方案需要完整并部署代码优先迁移以复制架构,此外,还需要包含一些“种子”数据,以便拥有完整的数据场景。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    • 2022-08-20
    • 2014-11-19
    • 1970-01-01
    • 2018-04-13
    • 1970-01-01
    相关资源
    最近更新 更多