跳至正文
首页 » 博客 » How to create relationships between entities in the Entity Framework Code First Approach

How to create relationships between entities in the Entity Framework Code First Approach

实体框架代码优先方法允许我们创建一个模型作为一个普通类,然后从域模型或实体类创建数据库。在代码优先的方法中,数据库从类创建。

,实体框架代码优先方法的一些优点包括 (如Scott Gu的博客中所述):

开发,而无需打开设计器或定义XML映射文件

定义你的模型对象通过简单地写 “普通的旧类” 没有基类的要求

: 使用 “约定优于配置” 的方法来实现数据库持久性,而无需明确配置任何东西

.选择覆盖基于约定的持久性,并使用流畅的代码API来完全自定义持久性映射

更深入地研究理论概念,在这篇文章中,我们将直接跳转到代码,并使用代码优先的方法创建表和数据库。在这篇文章中,我们将学习如何在实体框架代码优先方法中创建实体以及实体之间的关系。在EF代码第一种方法中,有两个选项可以通过以下方式创建实体之间的关系:

1.数据注释

2.流利的API

在这篇文章中,我们将使用数据注释来创建实体之间的关系。

创建数据库与一个表

让我们首先使用代码优先方法在数据库中创建一个名为Student的表。可以创建域类Student,如下面的列表所示:

CodeFirstDemoApp命名空间CodeFirstDemoApp

{

公共 课堂

学生

{

public int Id {get; set

; }

公共 字符串Name {get; set

; }

public int Age {get; set

; }

}

}

您可能已经注意到,学生班是一个普通的班级。实体框架将使用Student类在数据库中创建表。Student类表示域实体,它不应该具有数据库的任何信息或引用。实体框架将使用Student类创建Student表。

一旦创建了域实体类,接下来我们需要创建一个上下文类,它将继承DataContext类。可以创建上下文类,如下面的清单所示:

使用

System.Data.Entity;

CodeFirstDemoApp命名空间CodeFirstDemoApp

{

公共 上下文:

DbContext

{

公共上下文 () :

base ()

{

}

公共 DbSet<学生> 学生 {获取;设置;}

}

}

,我们使用默认构造函数创建了上下文类。在后面的文章中,我们将讨论构造函数中的各种选项。在context类中,我们正在执行以下任务:

·创建默认构造函数。由于我们没有在构造函数中传递任何参数,因此EF将创建一个名称为Namespace.Class姓名。所以在这种情况下,创建的数据库名称将是CodeFirstDemo.Context

·由于我们没有在Context类的构造函数中传递连接字符串信息,因此EF将在SQL server Express的默认数据库服务器中创建一个数据库。

·

在所需服务器中创建一个具有所需名称的数据库,我们需要创建连接字符串并将其作为上下文构造函数中的参数传递。

·若要在数据库中创建表,请创建泛型DbSet类型的公共属性,其中传递了域实体。

到目前为止,我们已经创建了Student实体类和Context类。现在我们可以编写一个简单的LINQ to Entity查询来创建数据库并执行如下所示的操作:

使用

系统;

使用

System.Linq;

CodeFirstDemoApp命名空间CodeFirstDemoApp

{

程序

{

静态 void Main( string

[] args)

{

CreateStudent();

控制台。写线 (“学生已创建”);

上下文c = 上下文

();

var result =

rc.学生选择r;

foreach (var r

结果)

{

控制台。WriteLine(r.Name);

}

控制台。ReadKey ();

}

静态 void

CreateStudent()

{

学生 = 学生

{

Id = 1,

年龄 = 12岁,

名称 =“Foo”

};

上下文c = 上下文

();

c.学生。添加 (s);

c.SaveChanges();

}

}

}

自定义数据库名称

,当我们使用上下文类的默认构造函数时,EF默认情况下会使用Namespace.Contextclass的完全限定名称创建数据库。但是,在这种情况下,我们可以在构造函数中传递数据库mydb的所需名称,如下面的清单所示:

公共

上下文 ()

:

base (“mydb”)

{

}

SQL Express EF中的

将创建一个名为mydb的数据库。

使用连接字符串

到目前为止,我们依靠EF来创建数据库。但是,我们可以传递一个连接字符串以在所需的服务器和名称上创建一个数据库。可以在配置文件中创建连接字符串,如下所示:

< connectionStrings >

<添加 姓名=democonnectionstring connectionString=数据源 =(LocalDb)\ v11.0; 初始目录 = Demo1; 集成安全性 = True;MultipleActiveResultSets = true providerName=System.Data.SqlClient<span style="background-image:none;background-repeat:repeat;background-attachment:scroll;background-position:0% 0%;mso-highlight:white;">" />

</connectionStrings>

我们创建了一个连接字符串,以便在本地db服务器中创建数据库。接下来,我们需要在Context类的构造函数中传递连接字符串名称,如下面的清单所示:

公共上下文 ()

:

base (name = democonnectionstring”))

{

}

关系实体

在代码优先的方法中,我们可以使用以下两个选项之一创建实体之间的关系:

1.数据注释

2.流利的API

在这篇文章中,我们将使用数据注释创建关系。

一对一关系

,我们可能需要在两个实体之间创建一对一的关系。换句话说,我们需要两个实体之间的主键-外键关系。假设我们有两个实体和以下规则:

1.有两个名为Student和StudentAccount的实体

2.学生是一个主要实体

3.StudentAccount是学生的依赖实体

4.StudentAccount的主键将是学生的外键

,如果没有学生,我们将无法创建学生帐户,并且学生帐户中只能有一个学生条目。简而言之,每个学生都有一个学生帐户,没有学生帐户就不会存在。

让我们首先创建主要实体: Student

公共

学生

{

public int Id {get; set

; }

公共 字符串Name {get; set

; }

public int Age {get; set

; }

公共 虚拟 StudentAccount StudentAccount {get; set

;

}

您可能已经注意到,在Student实体中,我们有一个类型为StudentAccount的虚拟属性,其创建如下所示:

公共 班级学生账户

{

public int Id {get; set

; }

公共 字符串Name {get; set

; }

公共 int金额 {get; set

; }

[

需要]

公共 虚拟 学生

学生 {get; set;; }

}

您可能已经注意到,在StudentAccount实体中,我们有一个学生类型的虚拟财产。由于Student是主要实体,因此需要注释StudentAccount实体中的虚拟Student属性。此外,可以创建一个上下文类,如下面的清单所示:

使用

System.Data.Entity;

CodeFirstDemoApp命名空间CodeFirstDemoApp

{

公共 上下文:

DbContext

{

公共环境 ()

:

base (name = democonnectionstring”))

{

}

公共 DbSet<学生> 学生 {获取;设置;}

公共 DbSet<学生帐户> StudentAccounts {获取;设置;}

}

}

永远记住,除非Student表中没有相应的行,否则我们无法在StudentAccounts表中创建行。可以在相关表中创建数据,如下面的列表所示:

静态 void

CreateStudent()

{

学生 = 学生

{

Id = 1,

年龄 = 12岁,

名称 =

“Foo”

};

StudentAccount sa = StudentAccount

{

金额 = 300,

名称 =

“体育帐户”

学生 = s

};

上下文c = 上下文

();

c.学生。添加 (s);

c.StudentAccounts.Add(sa);

c.SaveChanges();

}

您可能已经注意到,我们将Student对象设置为StudentAccount的属性。我们可以从两个表中检索记录,如下所示:

上下文c =新建 上下文();

var result =

rc.学生选择r;

foreach (var r

结果)

{

控制台。WriteLine(r.Name);

控制台。WriteLine(r.StudentAccounts.金额);

}

要验证SQL Server Management Studio中实体之间的关系,我们可以看到使用约束和键创建的列,如下图所示:

这里,StudentAccounts表的Id列既是主键又是外键。

一对多关系

我们可能需要在两个实体之间创建一个太多的关系。假设我们有两个实体

1.有两个实体Student和StudentAddress

2.学生是一个主要实体

3.StudentAddress是Student的依赖实体

4.一个学生可以注册多个StudentAddress

一个学生可以有多个学生地址。StudentAddress的列之一将具有外键作为Student的主键。

让我们首先创建主实体Student,

公共

学生

{

公共学生 ()

{

StudentAddresses =

HashSet < StudentAddress) >();

}

public int Id {get; set

; }

公共 字符串Name {get; set

; }

public int Age {get; set

; }

公共 ICollection<学生地址> 学生地址 {获取;设置;}

}

您可能已经注意到,我们正在创建StudentAddress的集合的属性,然后在Student的构造函数中创建StudentAddress属性的设置值。可以创建StudentAddress类,如下所示:

公共

学生地址

{

public int Id {get; set

; }

公共 字符串地址 {获取;设置;}

公共 int StudentId {get; set

; }

公共 虚拟 学生

学生 {get; set;; }

}

您可能已经注意到,在StudentAddress实体中,我们有一个类型为Student的虚拟财产。由于Student是主要实体,因此StudentAddress中的虚拟Student属性具有对应的StudentId属性。

进一步,可以创建上下文类,如下面的清单所示:

公共

上下文: DbContext

{

公共环境 ()

:

base (name = democonnectionstring”))

{

}

公共 DbSet<学生> 学生 {获取;设置;}

公共 DbSet<学生地址> 学生地址 {获取;设置;}

}

永远记住,我们不能在StudentAddress表中创建行,除非我们在Student表中没有相应的行。可以在相关表中创建数据,如下面的列表所示:

静态 void

CreateStudent()

{

学生 = 学生

{

Id = 1,

年龄 = 12岁,

名称 =“Foo”

};

StudentAddress sa1 = StudentAddress { Address =Delhi” ,Id = 1 };

学生地址sa2 =新建 学生地址{地址 =“班加罗尔”,Id = 2 };

s.StudentAddresses.Add(sa1);

s.StudentAddresses.Add(sa2);

上下文c = 上下文

();

c.学生。添加 (s);

c.SaveChanges();

}

您可能已经注意到,我们正在将StudentAddress的对象添加到Student中。我们可以从两个表中检索记录,如下所示:

静态

void Main( string [] args)

{

CreateStudent();

控制台。写线 (“学生已创建”);

上下文c = 上下文

();

var结果 =c.学生。包括 (“学生地址”)选择r;

foreach (var r

结果)

{

控制台。WriteLine(r.Name);

foreach(varar、学生地址)

{

控制台。WriteLine(a.地址);

}

}

控制台。ReadKey ();

}

要验证SQL Server Management Studio中实体之间的关系,我们可以看到使用约束和键创建的列,如下图所示:

多对多关系

最后但并非最不重要的是,让我们看看如何配置多对多关系。假设我们有一个学生实体和一个主题实体。一个学生可以注册许多科目,一个科目可以有许多学生。要在这些实体之间创建太多的关系,让我们首先创建Student实体,如下面的清单所示:

公共

学生

{

公共学生 ()

{

Subject =

HashSet < Subject > >();

}

public int Id {get; set

; }

公共 字符串Name {get; set

; }

public int Age {get; set

; }

公共 ICollection<主题> 受试者 {获取;设置;}

}

在这里,我们创建主题集合的属性,然后在Student的构造函数中创建主题属性的设置值。可以创建Subject类,如下面的清单所示:

公共

主题

{

公共主题 ()

{

学生 =

HashSet < Student () >;

}

public int Id {get; set

; }

公共 字符串Name {get; set

; }

公共 虚拟 ICollection<学生> 学生 {获取;设置;}

}

在主题类中,我们也正在创建学生集合的属性,并且在主题类的构造函数中创建一组学生。这就是我们需要做的,在实体之间建立太多关系。

进一步,可以创建上下文类,如下面的清单所示:

公共

上下文: DbContext

{

公共环境 ()

:

base (name = democonnectionstring”))

{

}

公共 DbSet<学生> 学生 {获取;设置;}

公共 DbSet<主题> 受试者 {获取;设置;}

}

我们可以在学生和科目表中创建行,如下所示:

静态 void

CreateStudent()

{

学生 = 学生

{

Id = 1,

年龄 = 12岁,

名称 =“Foo”

};

主题s1 =新建 主题{Id = 1, Name =“Phy”};

主题s2 =新建 主题{Id = 2, Name =“数学”};

s.主题。添加 (s1);

s.主题。添加 (s2);

上下文c = 上下文

();

c.学生。添加 (s);

c.SaveChanges();

}

我们可以从两个表中检索记录,如下所示:

静态

void Main( string [] args)

{

CreateStudent();

控制台。写线 (“学生已创建”);

上下文c = 上下文

();

var result = 来自rc.学生。包括 (“科目”) 选择r;

foreach (var r

结果)

{

控制台。WriteLine(r.Name);

foreach(varar.受试者)

{

控制台。WriteLine(a.Name);

}

}

控制台。ReadKey ();

}

当我们验证学生和主题实体之间的关系时,我们会发现EF创建了一个额外的表来维护多对多关系

所以你有它,这就是如何在代码第一种方法中创建实体之间的关系。在这篇文章中,我们开始使用单个实体,然后继续创建实体之间的关系。我希望你觉得这篇文章有用,感谢阅读。

Infragistics终极15.2在这里。下载看到它的力量在行动!

</p