C# 为MS SQL Compact Edition准备模型时,为什么同时使用本机引用和ID键来关联对象/实体?
在学习ASP.NET的过程中,我将遵循以下有关ASP.NET MVC4的教程: 作者准备创建数据库并将其实例放入该数据库的类。例如,他定义了类Album:C# 为MS SQL Compact Edition准备模型时,为什么同时使用本机引用和ID键来关联对象/实体?,c#,sql,asp.net-mvc,associations,C#,Sql,Asp.net Mvc,Associations,在学习ASP.NET的过程中,我将遵循以下有关ASP.NET MVC4的教程: 作者准备创建数据库并将其实例放入该数据库的类。例如,他定义了类Album: using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MvcMusicStore.Models { public class Album { public int AlbumId {
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcMusicStore.Models {
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; }
}
}
为什么我们必须保留与其他对象关联的冗余信息?我们得到:
GenreId
和原生引用Genre
。这是什么意思?据我所知,关系数据库保存ID而不是引用。因此,我们应该只保留ID。引用属性的目的是允许实体框架显式或隐式加载该引用的关联数据(延迟加载)。使用“引用”属性,可以执行以下操作:
album.Genre.Name;
获取流派的名称(假设它有一个名为name
)的属性)。但是,如果没有引用,您必须执行以下操作:
var genre = context.Genres.Find(album.GenreId);
genre.Name;
var album = context.Albums.Find(albumId); // 1 query
var artist = context.Artists.Find(album.ArtistId); // 1 query
var tours = context.Tours.Where(m => m.ArtistId == artist.Id); // 1 query
foreach (var tour in tours)
{
var shows = context.Shows.Where(m => m.TourId == tour.Id); // N queries
foreach (var show in shows)
{
// do something with show
}
}
然而,真正的力量来自组合查询的能力。如果您使用引用属性并提取相册,如:
context.Albums.Include("Genre").Find(albumId);
然后,当您访问类似于album.Genre.Name
的属性时,不会发出进一步的查询。实体框架在幕后进行了连接,并一次加载了所有数据。而如果没有reference属性,则必须发出两个查询才能到达这里。当考虑参考属性层时,这更为强大。例如,假设您的Artist
对象也有一个名为Tour
的类的引用属性,假设每个Tour
都有一个集合导航属性,指向Show
,这将是该巡演中的一个单独节目。然后你可以做:
context.Albums.Include("Artist.Tours.Shows").Find(albumId);
同时,不仅要查询专辑和艺术家,还要查询这些艺术家的所有巡演以及每个巡演中的所有演出。虽然这是一个很大的查询,但它是一个单一的查询——这是重要的部分。如果没有这些引用属性,则必须执行以下操作:
var genre = context.Genres.Find(album.GenreId);
genre.Name;
var album = context.Albums.Find(albumId); // 1 query
var artist = context.Artists.Find(album.ArtistId); // 1 query
var tours = context.Tours.Where(m => m.ArtistId == artist.Id); // 1 query
foreach (var tour in tours)
{
var shows = context.Shows.Where(m => m.TourId == tour.Id); // N queries
foreach (var show in shows)
{
// do something with show
}
}
您现在发出大量查询来获取所需的数据,而您可以只使用一个带有引用属性的查询