在为MS SQL Compact Edition准备模型时,为什么要同时使用本地引用和ID键来关联对象/实体?
本文关键字:ID 引用 实体 对象 关联 Edition Compact SQL MS 模型 为什么 | 更新日期: 2023-09-27 18:10:24
在学习ASP。. NET,我遵循这个教程的ASP。NET MVC4: http://www.asp.net/mvc/tutorials/mvc-music-store/mvc-music-store-part-4
Author准备了用于创建数据库并将其实例放入该数据库的类。他定义了实例类Album:
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
reference属性的目的是允许实体框架为该引用加载相关数据,无论是显式的还是隐式的(延迟加载)。使用reference属性,您可以这样做:
album.Genre.Name;
获取类型的名称(假设它有一个名为Name
的属性)。但是,如果没有引用,您将不得不执行如下操作:
var genre = context.Genres.Find(album.GenreId);
genre.Name;
然而,真正的力量来自于组合查询的能力。如果你使用引用属性并且你像这样获取你的专辑:
context.Albums.Include("Genre").Find(albumId);
然后,当您访问像album.Genre.Name
这样的属性时,不会发出进一步的查询。实体框架在后台做了一个连接,并一次加载了所有的数据。而如果没有reference属性,则必须发出两个查询才能到达这里。当您考虑引用属性层时,这将更加强大。例如,假设您的Artist
对象也有一个指向名为Tour
的类的引用属性,并且假设每个Tour
都有一个指向Show
的集合导航属性,这将是该巡回演出中的单个节目。你可以这样做:
context.Albums.Include("Artist.Tours.Shows").Find(albumId);
不仅可以同时查询专辑和艺术家,还可以查询这些艺术家的所有巡回演出以及每个巡回演出的所有演出。虽然这是一个大查询,但它是一个单个查询——这是重要的部分。如果没有这些引用属性,您将不得不这样做:
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
}
}
你现在发出一个吨查询来获得你需要的数据,而你可以只使用一个引用属性。