EF--payload or not

负载加载非负载加载适用于多对多场境。

一、非负载(payload-free)加载

  1.1创建表

create table Album
(
    AlbumId int primary key identity(1,1),
    AlbumName varchar(20)
)

create table Artist
(
 ArtistId int identity(1,1) primary key,
 FirstName varchar(20),
 MiddleName varchar(20),
 LastName varchar(20)
)


create table LinkTable
(
    ArtistId int ,
    AlbumId int ,
    primary key (ArtistId, AlbumId),
    foreign key (ArtistId) references Artist(ArtistId),
    foreign key (AlbumId) references Album(AlbumId)
)
View Code

 

  1.2、添加项目及数据实体对象

  新建控制台项目,使用DBFirst添加生成Model对象,生成对象时选择添加的表。实体添加后如下

  

  非负载(payload)加载时中间表LinkTable除了主键没有多余属性,EF不会将这类表生成实体而是做为实体关系生成。

  1.3、数据操作

  操作代码:  

  class Program
    {
        static void Main(string[] args)
        {
            using (var context = new EF6RecipesEntities())
            {
                //Artist对应多个Album
                var artist = new Artist { FirstName = "Alan", LastName = "Jackson" };
                var album1 = new Album { AlbumName = "Drive" };
                var album2 = new Album { AlbumName = "Live at " };
                artist.Albums.Add(album1);
                artist.Albums.Add(album2);
                context.Artists.Add(artist);

                // Album对应多个Artist
                var artist1 = new Artist { FirstName = "Tobby", LastName = "Keith" };
                var artist2 = new Artist { FirstName = "Merle", LastName = "Haggard" };
                var album = new Album { AlbumName = "Honkytonk" };
                artist1.Albums.Add(album);
                artist2.Albums.Add(album);
                context.Albums.Add(album);
                context.SaveChanges();


                Console.WriteLine("Artists and their albums");
                var artists = context.Artists;

                foreach (var item in artists)
                {
                    Console.WriteLine("{0}{1}", item.FirstName, item.LastName);
                    foreach (var album_temp in item.Albums)
                    {
                        Console.WriteLine("\t{0}", album_temp.AlbumName);
                    }
                }


                Console.WriteLine("Artists and their albums");
                var Albums = context.Albums;

                foreach (var item_temp in Albums)
                {
                    Console.WriteLine("{0}", item_temp.AlbumName);
                    foreach (var art_temp in item_temp.Artists)
                    {
                        Console.WriteLine("\t{0}{1}", art_temp.FirstName, art_temp.LastName);
                    }
                }

                Console.ReadKey();
            }
        }
    }
View Code

  运行结果如下:

  

 

 

二、负载(payload-rich)加载

  2.1 修改表

   继续使用上面的项目,删除重建LinkTable表,并清除旧数据。  

--删除重建关联表
drop table linkTable
create table LinkTable
(
    ArtistId int ,
    AlbumId int ,
    comment varchar(200),
    primary key (ArtistId, AlbumId),
    foreign key (ArtistId) references Artist(ArtistId),
    foreign key (AlbumId) references Album(AlbumId)
)
--清空旧数据
delete from Album
delete from Artist
View Code

  2.2重新生成Model实体

  在项目打开实体视图,删除所有已添加的对象。再右键 选择从数据库更新模型。选择表生成后实体关系如下。

  

  由于中间表有标量属性comment,所以EF在生成实体时会连接表做为实体生成,并且生成两个一对多关系。

  2.3数据操作

  

    class Program
    {
        static void Main(string[] args)
        {
            using (var context = new EF6RecipesEntities())
            {
                //Artist对应多个Album
                var artist = new Artist { FirstName = "Alan", LastName = "Jackson" };
                var album1 = new Album { AlbumName = "Drive" };
                var linkTab = new LinkTable { Album = album1, Artist = artist, comment = "Comment1" };



                var album2 = new Album { AlbumName = "Drive album2" };

                linkTab = new LinkTable { Artist = artist, Album = album2, comment = "Comment2" };

                context.Artists.Add(artist);
                context.SaveChanges();

                context.LinkTables.Add(linkTab);
                context.SaveChanges();

                foreach (var item in context.Artists)
                {
                    Console.WriteLine("{0}{1}", item.FirstName, item.LastName);
                    foreach (var table in item.LinkTables)
                    {
                        Console.WriteLine("\t{0}{1}", table.comment, table.Album.AlbumName);
                    }
                }

                Console.ReadKey();
            }
        }
    }
View Code

  2.4运行结果

  

  2.5 最佳实践

   负载(payload-rich)情形下,为了适应扩展和对应关系,这种情况下中间表设置自己的主键。

  

  

 

posted @ 2017-07-26 05:44  mopheify  阅读(150)  评论(0编辑  收藏  举报