|
系列文章导航:
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进阶系列(四)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进阶系列(四)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关系,转载需保留来源!
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。