系列文章導航:
Linq To Sql進階系列(一)從映射講起
Linq To Sql進階系列(二)M:M關系
Linq To Sql進階系列(三)CUD和Log
Linq To Sql進階系列(四)User Define Function篇
Linq To Sql進階系列(五)Store Procedure篇
Linq To Sql進階系列(六)用object的動態查詢與保存log篇
Linq To Sql進階系列(七)動態查詢續及CLR與SQL在某些細節上的差別
在Linq To Sql進階系列(一) 一文中,我們談到了數據庫中的兩種基本關系1:M 與1:1. 而現實世界中,還有一種M:M 的關系。比如,一個老師可以有多個學生,而一個學生也可以有多個老師。老師和學生的關系就是多對多的關系。這些關系在數據庫中是如何反映的呢?
在C#3.0入門系列(十)-之Join操作一文中,我們提到了M:M 的關系中的join操作。哦,原來,M:M 的關系在數據庫中,依然是通過1:M 來體現。比如,在一個域內,一個User可以加入到多個Group中,一個Group也可以包含多個User。 User與Group并沒有直接的關系,而是通過第三個表UserInGroup發生關系。User與 UserInGroup的關系為1:M,其關系鍵為UserId, 而Group與 UserInGroup的關系也為1:M, 其關系鍵為GroupId,這樣,我們通過第三個表,讓User與Group發生了關系,他們的關系為M:M.
這三個表的腳本如下:


SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[User]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[User](
[UserId] [nchar](10) NOT NULL,
[UserName] [nchar](10) NULL,
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED
(
[UserId] ASC
) ON [PRIMARY]
) ON [PRIMARY]
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[Group]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[Group](
[GroupId] [nchar](10) NOT NULL,
[GroupName] [nchar](10) NULL,
CONSTRAINT [PK_Group] PRIMARY KEY CLUSTERED
(
[GroupId] ASC
) ON [PRIMARY]
) ON [PRIMARY]
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[UserInGroup]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[UserInGroup](
[UserId] [nchar](10) NOT NULL,
[GroupId] [nchar](10) NOT NULL,
CONSTRAINT [PK_UserInGroup] PRIMARY KEY CLUSTERED
(
[UserId] ASC,
[GroupId] ASC
) ON [PRIMARY]
) ON [PRIMARY]
END
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_UserInGroup_Group]') AND type = 'F')
ALTER TABLE [dbo].[UserInGroup] WITH CHECK ADD CONSTRAINT [FK_UserInGroup_Group] FOREIGN KEY([GroupId])
REFERENCES [dbo].[Group] ([GroupId])
GO
ALTER TABLE [dbo].[UserInGroup] CHECK CONSTRAINT [FK_UserInGroup_Group]
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_UserInGroup_User]') AND type = 'F')
ALTER TABLE [dbo].[UserInGroup] WITH CHECK ADD CONSTRAINT [FK_UserInGroup_User] FOREIGN KEY([UserId])
REFERENCES [dbo].[User] ([UserId])
GO
ALTER TABLE [dbo].[UserInGroup] CHECK CONSTRAINT [FK_UserInGroup_User]
系列文章導航:
Linq To Sql進階系列(一)從映射講起
Linq To Sql進階系列(二)M:M關系
Linq To Sql進階系列(三)CUD和Log
Linq To Sql進階系列(四)User Define Function篇
Linq To Sql進階系列(五)Store Procedure篇
Linq To Sql進階系列(六)用object的動態查詢與保存log篇
Linq To Sql進階系列(七)動態查詢續及CLR與SQL在某些細節上的差別
創建數據庫后,添加一些數據供測試。


insert into [User] values('Tom Song','Tom Song')
insert into [User] values('Guoan Song','Guoan Song')

insert into [Group] values ('Csharp','Csharp Team')
insert into [Group] values ('Dlinq','Dlinq Team')

insert into UserInGroup values ('Tom Song','Csharp')
insert into UserInGroup values ('Tom Song','Dlinq')
insert into UserInGroup values ('Guoan Song','Csharp')
insert into UserInGroup values ('Guoan Song','Dlinq') 系列文章導航:
Linq To Sql進階系列(一)從映射講起
Linq To Sql進階系列(二)M:M關系
Linq To Sql進階系列(三)CUD和Log
Linq To Sql進階系列(四)User Define Function篇
Linq To Sql進階系列(五)Store Procedure篇
Linq To Sql進階系列(六)用object的動態查詢與保存log篇
Linq To Sql進階系列(七)動態查詢續及CLR與SQL在某些細節上的差別
為了不破壞數據庫的映射,我們把這部分改動放到partial class中。這樣,我們渴望實現user.Group。
我們來做個測試,看看是不是成功了呢。


public static void Main(string[] arg)

{
DataClasses1DataContext db = new DataClasses1DataContext();
db.Log = Console.Out;
var userSet = (from u in db.Users
select u).ToList();
foreach (var use in userSet)

{
foreach (var group in use.Groups)

{
Console.WriteLine(group.GroupName);
}
}

var groupSet = (from u in db.Groups
select u).ToList();
foreach (var group in groupSet)

{
foreach (var user in group.Users)

{
Console.WriteLine(user.UserName);
}
}
}
it知識庫:Linq To Sql進階系列(二)M:M關系,轉載需保留來源!
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。