第二章(3)建立不带负载的多对多模型

问题:

     在你的数据库中有几张表,它们是通过链接或者是中间链接表关联在一起。链接表中只包含了将这两张表连接成多对多关系的外键。现在你想把这些表都导入到多对多模型中。

解决过程:

   我们假设你的数据库是如图2-3-1所示的情况:

图2-3-1

要想把这三张表都导入到你的多对多关系模型中,需要做以下几件事:

  1.  在你的项目上右键,添加新项,选择ADO.NET Entity Data Model。
  2. 选择从数据库中生成模型,点击下一步。
  3. 使用向导,选择一个既有数据库连接或者新建一个连接。
  4. 在选择你的数据库对象的对话框中,选择表Album、LinkTable和Artist。并保持最下面两个复选框选中的状态。点击完成。向导会为你创建如图2-3-2的模型。


图2-3-2

在Album和Artist之间的多对多的关系,用一条两端标有“*”的线表示。因为一个歌手可以有很多专辑,一张专辑也可以由很多歌手一起创作,所以在这两个实体中的导航属性都是集合类型的。

原理:

      注意到LinkTable并没有在图2-3-2中的模型中显示,因为我们的LinkTable没有标量属性(也就是没有有效负载),EF就认为这个表存在的唯一目的就是将Ablum表和Artist表联合在一起。如果LinkTable有标量属性的话,EF创建的模型就不是现在这个样子了,这个我们在下一节会看到。

      下面的代码演示了怎么往我们的模型中插入新的albums和artists记录,怎么样从模型中根据artist查询他们的albums以及怎么根据albums查询创作它的artist。

Insert artists and albums
            using (var context = new EFRecipesEntities())
            {
                // add an artist with two albums
                var artist = new Artist { FirstName = "Alan", LastName = "Jackson" };
                var album1 = new Album { AlbumName = "Drive" };
                var album2 = new Album { AlbumName = "Live at Texas Stadium" };
                artist.Albums.Add(album1);
                artist.Albums.Add(album2);
                context.Artists.AddObject(artist);
                // add an album for two artists
                var artist1 = new Artist { FirstName = "Tobby", LastName = "Keith" };
                var artist2 = new Artist { FirstName = "Merle", LastName = "Haggard" };
                var album = new Album { AlbumName = "Honkytonk University" };
                artist1.Albums.Add(album);
                artist2.Albums.Add(album);
                context.Albums.AddObject(album);
                context.SaveChanges();
            }
Query artists and albums
            using (var context = new EFRecipesEntities())
            {
                Console.WriteLine("Artists and their albums...");
                var artists = from a in context.Artists select a;
                foreach (var artist in artists)
                {
                    Console.WriteLine("{0} {1}", artist.FirstName, artist.LastName);
                    foreach (var album in artist.Albums)
                    {
                        Console.WriteLine("\t{0}", album.AlbumName);
                    }
                }
                Console.WriteLine("\nAlbums and their artists...");
                var albums = from a in context.Albums select a;
                foreach (var album in albums)
                {
                    Console.WriteLine("{0}", album.AlbumName);
                    foreach (var artist in album.Artists)
                    {
                        Console.WriteLine("\t{0} {1}", artist.FirstName, artist.LastName);
                    }
                }
            }
output
----------------------------
Artists and their albums...
Alan Jackson
Drive
Live at Texas Stadium
Tobby Keith
Honkytonk University
Merle Haggard
Honkytonk University
Albums and their artists...
Drive
Alan Jackson
Live at Texas Stadium
Alan Jackson
Honkytonk University
Tobby Keith
Merle Haggard
-----------------------------

  在得到objectcontext实例之后,我们创建并实例化了一个Artist的实体和若干个Albums实体,并把albums加入到artist中,最后把artist加入到objectContext中(这样实例对象才能被跟踪)。

接着,我们创建了一个Artist实例,并赋上了一个album。这是因为两个artist共同创作了一个album。我们把这个album分别就加到两个artist的导航属性中。同时把albums加入context中。完成了这些之后,调用SaveChanges()方法,把这些改变保存到数据库。

  当我们用一个全新的ObjectContext查询数据库时,我们把抓取artists,把他们的ablums输出;抓取albums,把相关的artists输出。

  注意到我们在代码中并没有涉及到LinkTable这张表。实际上这张表并没有在我们模型实体中,它代表的仅是Artists和Albums之间导航属性的多对多关系。

posted @ 2012-08-26 15:39  阿凡迪  阅读(553)  评论(5编辑  收藏  举报