65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Code First 方法和 Fluent API 在 Entity Framework 中建立关系

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.87/5 (80投票s)

2014年7月14日

CPOL

10分钟阅读

viewsIcon

277385

downloadIcon

4342

在本文中,您将学习如何在 Entity Framework 中使用 Code First 方法和 Fluent API 处理关系。

引言

在数据库的上下文中,关系是指两个关系数据库表之间存在的一种情况,其中一个表有一个引用另一个表主键的外键。关系允许关系数据库将数据拆分并存储在不同的表中,同时链接不同的数据项。例如,如果我们想存储关于 `Customer` 及其 `Order` 的信息,那么我们需要创建两个表,一个用于 `Customer`,另一个用于 `Order`。 `Customer` 和 `Order` 这两个表将具有一对多关系,因此每当我们检索一个 `customer` 的所有订单时,我们都可以轻松地检索它们。

数据库关系有几种类型。在本文中,我将介绍以下内容

  • 一对一关系
  • 一对多或多对一关系
  • 多对多关系

Entity Framework Code First 允许我们使用自己的域类来表示 Entity Framework 依赖的模型,以执行查询、更改跟踪和更新功能。Code First 方法遵循约定优于配置的原则,但它也提供了两种方式为我们的类添加配置。一种是使用简单的属性,称为 `DataAnnotations`,另一种是使用 Code First 的 Fluent API,它提供了一种通过代码以命令式的方式描述配置的方法。本文将重点介绍 Fluent API 中关系的处理。

为了理解 Entity Framework Code First 方法中的关系,我们创建一个实体并使用 Fluent API 定义它们的配置。我们将创建两个类库项目,一个库项目 (`EF.Core`) 包含实体,另一个项目 (`EF.Data`) 包含这些实体的配置以及 `DbContext`。我们还将创建一个单元测试项目 (`EF.UnitTest`) 来测试我们的代码。我们将使用下面的类图中的类来解释前面的三种关系。

Class Diagram for Entities

图 1.1 实体类图。

如前面的类图所示,`BaseEntity` 类是每个其他类继承的基类。每个派生实体代表一个数据库表。我们将使用左侧的两个派生实体组合来解释每种关系类型,因此我们创建了六个实体。

所以,首先,我们在 `EF.Core` 类库项目下创建 `BaseEntity` 类,该类被每个派生实体继承。

using System;    
namespace EF.Core  
{  
  public abstract  class BaseEntity  
    {  
        public Int64 ID { get; set; }  
        public DateTime AddedDate { get; set; }  
        public DateTime ModifiedDate { get; set; }  
        public string IP { get; set; }  
    }  
}

我们使用导航属性来访问一个相关实体对象。导航属性提供了一种导航两个实体类型之间关联的方法。每个对象都可以拥有其参与的每个关系的一个导航属性。导航属性允许您双向导航和管理关系,返回一个引用对象(如果基数是一个或零到一)或一个集合(如果基数是多)。

现在我们一一来看每种关系。

学习使用 Entity Framework 进行 MVC 的路线图

一对一关系

在关系的两边,两个表都只能有一个记录。每个主键值只与相关表中的一个记录(或无记录)相关。请注意,这种类型的关系并不常见,大多数一对一关系是由业务规则强制执行的,而不是自然地从数据中产生的。在没有此类规则的情况下,通常可以将两个表合并为一个表,而不会破坏任何规范化规则。

为了理解一对一关系,我们创建两个实体,一个是 `User`,另一个是 `UserProfile`。一个用户可以有一个配置文件,`User` 表将有一个主键,同一个键将是 `UserProfile` 表的主键和外键。让我们来看图 1.2 了解一对一关系。

One-to-One Relationship

图 1.2:一对一关系

现在我们在 `EF.Core` 项目的 *Data* 文件夹下创建 `User` 和 `UserProfile` 这两个实体。我们的 `User` 类代码片段如下:

namespace EF.Core.Data  
{  
   public class User : BaseEntity  
    {  
        public string UserName { get; set; }  
        public string Email { get; set; }  
        public string Password { get; set; }  
        public UserProfile UserProfile { get; set; }  
    }  
} 

`UserProfile` 类代码片段如下:

namespace EF.Core.Data  
{  
   public class UserProfile : BaseEntity   
    {  
        public string FirstName { get; set; }  
        public string LastName { get; set; }  
        public string Address { get; set; }  
        public virtual User User { get; set; }  
    }  
} 

从前面的两个代码片段可以看出,每个实体都使用另一个实体作为导航属性,以便您可以访问彼此相关的对象。

现在,我们定义这两个实体的配置,当实体创建数据库表时将使用这些配置。该配置在 `EF.Data` 项目下的 *Mapping* 文件夹中定义。现在为每个实体创建两个配置类。对于 `User` 实体,我们创建 `UserMap` 实体。

using System.ComponentModel.DataAnnotations.Schema;  
using System.Data.Entity.ModelConfiguration;  
using EF.Core.Data;  
  
namespace EF.Data.Mapping  
{  
    public class UserMap : EntityTypeConfiguration<User>  
    {  
        public UserMap()  
        {  
            //Key  
            HasKey(t => t.ID);  
  
            //Fields  
            Property(t => t.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);  
            Property(t => t.UserName).IsRequired().HasMaxLength(25);  
            Property(t => t.Email).IsRequired();  
            Property(t => t.AddedDate).IsRequired();  
            Property(t => t.ModifiedDate).IsRequired();  
            Property(t => t.IP);  
  
            //table  
            ToTable("Users");  
        }  
    }  
}  

我们将以与 `User` 相同的方式为其他实体创建配置。`EntityTypeConfiguration `是一个重要的类,它允许在模型中为实体类型执行配置。这是通过在 `OnModelCreate` 方法的重写中使用 `modelbuilder` 来完成的。`UserMap` 类的构造函数使用 Fluent API 来映射和配置表中的属性。因此,我们一一来看构造函数中使用的每个方法。

  1. `HasKey()`:`Haskey()` 方法配置表的主键。
  2. `Property()`:`Property` 方法配置属于实体或复杂类型的每个属性的属性。它用于获取给定属性的配置对象。配置对象上的选项特定于正在配置的类型。
  3. `HasDatabaseGeneratedOption`:它配置数据库如何生成属性的值。
  4. `DatabaseGeneratedOption.Identity`:`DatabaseGeneratedOption` 是数据库注解。它枚举数据库生成选项。`DatabaseGeneratedOption.Identity` 用于通过唯一值在表中创建自动递增列。
  5. `ToTable()`:配置此实体类型映射到的表名。

现在创建 `UserProfile` 配置类,即 `UserProfileMap` 类。

using System.Data.Entity.ModelConfiguration;  
using EF.Core.Data;  
  
namespace EF.Data.Mapping  
{  
    public class UserProfileMap : EntityTypeConfiguration<UserProfile>  
    {  
        public UserProfileMap()  
        {  
            //key  
            HasKey(t => t.ID);  
  
            //fields  
            Property(t => t.FirstName);  
            Property(t => t.LastName);  
            Property(t => t.Address).HasMaxLength(100).HasColumnType("nvarchar");  
            Property(t => t.AddedDate);  
            Property(t => t.ModifiedDate);  
            Property(t => t.IP);  
  
            //table  
            ToTable("UserProfiles");  
  
            //relationship  
            HasRequired(t => t.User).WithRequiredDependent(u => u.UserProfile);  
        }  
    }  
}  

在上面的代码片段中,我们定义了 `User` 和 `UserProfiles` 实体之间的“一对一”关系。这种关系是通过 Fluent API 使用 `HasRequired()` 和 `WithRequiredDependent()` 方法定义的,因此这些方法如下:

  1. `HasRequired()`:配置此实体类型的必需关系。除非指定了此关系,否则实体类型的实例将无法保存到数据库。数据库中的外键将不可为空。换句话说,`UserProfile` 不能独立于 `User` 实体保存。
  2. `WithRequiredDependent()`:(来自 MSDN)将关系配置为必需:必需,但关系另一侧没有导航属性。要配置的实体类型将是依赖项,并包含指向主键的外键。关系目标指向的实体类型将是关系中的主键。

现在在 `EF.Data` 项目下的 *App.config* 文件中定义连接字符串,以便我们可以创建具有适当名称的数据库。`connectionstring` 是:

<connectionStrings>  
    <add name="DbConnectionString" connectionString="Data Source=sandeepss-PC;
    Initial Catalog=EFCodeFirst;User ID=sa; Password=*******" providerName="System.Data.SqlClient" />  
</connectionStrings> 

现在我们创建一个继承 `DbContext` 类的上下文类 `EFDbContext`(*EFDbContext.cs*)。在此类中,我们重写 `OnModelCreating()` 方法。当上下文类 (`EFDbContext`) 的模型初始化后,但在模型被锁定并用于初始化上下文之前,会调用此方法,以便在模型被锁定前可以进一步配置模型。以下是上下文类的代码片段。

using System;  
using System.Data.Entity;  
using System.Data.Entity.ModelConfiguration;  
using System.Linq;  
using System.Reflection;  
  
namespace EF.Data  
{  
   public class EFDbContext : DbContext  
    {  
       public EFDbContext()  
           : base("name=DbConnectionString")  
       {  
           
       }  
         
       protected override void OnModelCreating(DbModelBuilder modelBuilder)  
       {  
            var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()  
           .Where(type => !String.IsNullOrEmpty(type.Namespace))  
           .Where(type => type.BaseType != null && type.BaseType.IsGenericType  
                && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));  
           foreach (var type in typesToRegister)  
           {  
               dynamic configurationInstance = Activator.CreateInstance(type);  
               modelBuilder.Configurations.Add(configurationInstance);  
           }  
           base.OnModelCreating(modelBuilder);  
       }  
    }  
} 

正如您所知,EF Code First 方法遵循约定优于配置的原则,因此在构造函数中,我们只需传递连接字符串名称,与 *App.Config* 文件中的名称相同,它就会连接到该服务器。在 `OnModelCreating()` 方法中,我们使用反射将实体映射到此特定项目中的其配置类。

我们创建一个单元测试项目 `EF.UnitTest` 来测试上述代码。我们创建一个名为 `UserTest` 的测试类,其中有一个名为 `UserUserProfileTest()` 的测试方法。此方法创建一个数据库,并根据 `User` 和 `UserProfile` 表的关系填充它们。以下是 `UserTest` 类的代码片段。

using System;  
using System.Data.Entity;  
using EF.Core.Data;  
using EF.Data;  
using Microsoft.VisualStudio.TestTools.UnitTesting;  
  
namespace EF.UnitTest  
{  
    [TestClass]  
    public class UserTest  
    {  
        [TestMethod]  
        public void UserUserProfileTest()  
        {  
            Database.SetInitializer<EFDbContext>(new CreateDatabaseIfNotExists<EFDbContext>());  
            using (var context = new EFDbContext())  
            {  
                context.Database.Create();  
                User user = new User  
                {  
                    UserName = "ss_shekhawat",  
                    Password = "123",  
                    Email = "sandeep.shekhawat88@test.com",  
                    AddedDate = DateTime.Now,  
                    ModifiedDate = DateTime.Now,  
                    IP = "1.1.1.1",  
                    UserProfile = new UserProfile  
                    {  
                        FirstName ="Sandeep",  
                        LastName ="Shekhawat",  
                        Address="Jaipur and Jhunjhunu",                          
                        AddedDate = DateTime.Now,  
                        ModifiedDate = DateTime.Now,  
                        IP = "1.1.1.1"  
                    },  
                };  
                context.Entry(user).State = System.Data.EntityState.Added;  
                context.SaveChanges();  
            }  
        }  
    }  
}  

现在,运行 `Test` 方法,您将在数据库中看到具有数据的表。在数据库中运行 `select` 查询并获取结果,例如:

SELECT [ID],[UserName],[Email],[Password],[AddedDate],[ModifiedDate],[IP]FROM [EFCodeFirst].[dbo].[Users]  
    
SELECT [ID],[FirstName],[LastName],[Address],[AddedDate]      ,[ModifiedDate],[IP] FROM [EFCodeFirst].[dbo].[UserProfiles]  

现在执行前面的查询,然后您将看到以下图中的结果:

Result of User and UserProfile

图 1.3:User 和 UserProfile 的结果。

一对多关系

主键表只包含一条记录,该记录与相关表中的零个、一个或多个记录相关。这是最常用的一种关系。

为了理解这种关系,我们考虑一个电子商务系统,其中单个用户可以进行许多订单,因此我们定义两个实体,一个用于 `customer`,另一个用于 `order`。让我们看一下下图:

One-to-many Relationship

图 1.4 一对多关系

`customer` 实体如下:

using System.Collections.Generic;  
  
namespace EF.Core.Data  
{  
  public  class Customer : BaseEntity   
    {  
      public string Name { get; set; }  
      public string Email { get; set; }  
      public virtual ICollection<Order> Orders { get; set; }  
    }  
}

`Order` 实体代码片段如下:

using System;  
  
namespace EF.Core.Data  
{  
    public class Order : BaseEntity  
    {  
        public byte Quanatity { get; set; }  
        public Decimal Price { get; set; }  
        public Int64 CustomerId { get; set; }  
        public virtual Customer Customer { get; set; }  
    }  
} 

您已注意到上面的代码中的导航属性。`Customer` 实体具有 `Order` 实体类型的集合,而 `Order` 实体具有 `Customer` 实体类型的属性,这意味着一个 `customer` 可以进行多个 `order`。

现在在 `EF.Data` 项目中创建一个类 `CustomerMap`,以实现 `Customer` 类的 Fluent API 配置。

using System.ComponentModel.DataAnnotations.Schema;  
using System.Data.Entity.ModelConfiguration;  
using EF.Core.Data;  
  
namespace EF.Data.Mapping  
{  
   public class CustomerMap : EntityTypeConfiguration<Customer>  
    {  
       public CustomerMap()  
       {  
           //key  
           HasKey(t => t.ID);  
  
           //properties  
           Property(t => t.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);  
           Property(t => t.Name);  
           Property(t => t.Email).IsRequired();  
           Property(t => t.AddedDate).IsRequired();  
           Property(t => t.ModifiedDate).IsRequired();  
           Property(t => t.IP);  
  
           //table  
           ToTable("Customers");  
       }  
    }  
}  

现在为 `Order` 实体配置创建一个另一个映射类。

using System.ComponentModel.DataAnnotations.Schema;  
using System.Data.Entity.ModelConfiguration;  
using EF.Core.Data;  
  
namespace EF.Data.Mapping  
{  
   public class OrderMap : EntityTypeConfiguration<Order>  
    {  
       public OrderMap()  
       {  
           //key  
           HasKey(t => t.ID);  
  
           //fields  
           Property(t => t.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);  
           Property(t => t.Quanatity).IsRequired().HasColumnType("tinyint");  
           Property(t => t.Price).IsRequired();  
           Property(t => t.CustomerId).IsRequired();  
           Property(t => t.AddedDate).IsRequired();  
           Property(t => t.ModifiedDate).IsRequired();  
           Property(t => t.IP);  
  
           //table  
           ToTable("Orders");  
  
           //relationship  
           HasRequired(t => t.Customer).WithMany(c => c.Orders).HasForeignKey_
                   (t => t.CustomerId).WillCascadeOnDelete(false);  
       }  
    }  
} 

上面的代码显示,每个订单都要求有一个 `Customer`,并且 `Customer` 可以进行多个订单,它们之间的关系由外键 `CustomerId` 建立。在这里,我们使用四种方法来定义两个实体之间的关系。`WithMany` 方法允许我们指示 `Customer` 中的哪个属性包含多重关系。我们还添加了 `HasForeignKey` 方法来指示 `Order` 中的哪个属性是回指 `customer` 的外键。`WillCascadeOnDelete()` 方法配置是否为该关系启用级联删除。

现在,我们在 `EF.UnitTest` 项目中创建另一个单元测试类来测试上面的代码。让我们看一个插入具有两个订单的客户数据的测试方法。

using System;  
using System.Collections.Generic;  
using System.Data.Entity;  
using EF.Core.Data;  
using EF.Data;  
using Microsoft.VisualStudio.TestTools.UnitTesting;  
  
namespace EF.UnitTest  
{  
    [TestClass]  
    public class CustomerTest  
    {  
        [TestMethod]  
        public void CustomerOrderTest()  
        {  
             Database.SetInitializer<EFDbContext>(new CreateDatabaseIfNotExists<EFDbContext>());  
             using (var context = new EFDbContext())  
             {  
                 context.Database.Create();  
                 Customer customer = new Customer  
                                     {  
                                         Name = "Raviendra",  
                                         Email = "raviendra@test.com",  
                                         AddedDate = DateTime.Now,  
                                         ModifiedDate = DateTime.Now,  
                                         IP = "1.1.1.1",  
                                         Orders = new List<Order>{  
                                            new Order  
                                            {  
                                                Quanatity =12,  
                                                Price =15,  
                                                AddedDate = DateTime.Now,  
                                                ModifiedDate = DateTime.Now,  
                                                 IP = "1.1.1.1",  
                                            },  
                                            new Order  
                                            {  
                                                Quanatity =10,  
                                                Price =25,  
                                                AddedDate = DateTime.Now,  
                                                ModifiedDate = DateTime.Now,  
                                                 IP = "1.1.1.1",  
                                            }  
                                        }  
                                     };  
                 context.Entry(customer).State = System.Data.EntityState.Added;  
                 context.SaveChanges();  
             }  
        }  
    }  
} 

现在运行 `Test` 方法,您将在数据库中看到具有数据的表。在数据库中运行 `select` 查询并获取结果,例如:

SELECT [ID],[Name],[Email],[AddedDate],[ModifiedDate],[IP]FROM [EFCodeFirst].[dbo].[Customers]  
SELECT [ID],[Quanatity],[Price],[CustomerId],[AddedDate],[ModifiedDate],[IP]FROM [EFCodeFirst].[dbo].[Orders] 

Customer and Order Data

图 1.5 Customer 和 Order 数据。

多对多关系

两个表中的每个记录都可以与另一个表中的任意数量的记录(或无记录)相关。多对多关系需要第三个表,称为关联表或链接表,因为关系系统无法直接容纳这种关系。

为了理解这种关系,我们考虑一个在线课程系统,其中一个 `student` 可以加入多个 `courses`,而一个 `course` 可以有多个 `students`。因此,我们定义了两个实体,一个用于 `student`,另一个用于 `course`。让我们看一下下面的多对多关系图:

Many-to-Many Relationship

图 1.6 多对多关系。

`Student` 实体如下面的代码片段所示,它定义在 `EF.Core` 项目下。

using System.Collections.Generic;  
  
namespace EF.Core.Data  
{  
    public class Student : BaseEntity  
    {  
        public string Name { get; set; }  
        public byte Age { get; set; }  
        public bool IsCurrent { get; set; }  
        public virtual ICollection<Course> Courses { get; set; }  
    }  
}

`Course` 实体如下面的代码片段所示,它定义在 `EF.Core` 项目下。

using System;  
using System.Collections.Generic;  
  
namespace EF.Core.Data  
{  
   public class Course : BaseEntity  
    {  
       public string Name { get; set; }  
       public Int64 MaximumStrength { get; set; }  
       public virtual ICollection<Student> Students { get; set; }  
    }  
}

上面两个代码片段都具有集合形式的导航属性,换句话说,一个实体拥有另一个实体集合。

现在在 `EF.Data` 项目中创建一个名为 `StudentMap` 的类,以实现 `Student` 类的 Fluent API 配置。

using System.ComponentModel.DataAnnotations.Schema;  
using System.Data.Entity.ModelConfiguration;  
using EF.Core.Data;  
  
namespace EF.Data.Mapping  
{  
   public class StudentMap : EntityTypeConfiguration<Student>  
    {  
       public StudentMap()  
       {  
           //key  
           HasKey(t => t.ID);  
  
           //property  
           Property(t => t.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);  
           Property(t => t.Name);  
           Property(t => t.Age);  
           Property(t => t.IsCurrent);  
           Property(t => t.AddedDate).IsRequired();  
           Property(t => t.ModifiedDate).IsRequired();  
           Property(t => t.IP);  
  
           //table  
           ToTable("Students");  
  
           //relationship  
           HasMany(t => t.Courses).WithMany(c => c.Students)  
                                .Map(t => t.ToTable("StudentCourse")  
                                    .MapLeftKey("StudentId")  
                                    .MapRightKey("CourseId"));  
       }  
    }  
}  

上面的代码片段显示,一个 `student` 可以加入多个 `courses`,而每个 `course` 可以有多个 `students`。众所周知,要实现多对多关系,我们需要一个名为 `StudentCourse` 的第三个表。`MapLeftKey()` 和 `MapRightKey()` 方法定义了第三个表中的键名,否则键名会自动创建为 `classname_Id`。左键或第一个键是我们正在定义关系所在的键。

现在在 `EF.Data` 项目中创建一个名为 `CourseMap` 的类,以实现 `Course` 类的 Fluent API 配置。

using System.ComponentModel.DataAnnotations.Schema;  
using System.Data.Entity.ModelConfiguration;  
using EF.Core.Data;  
  
namespace EF.Data.Mapping  
{  
   public class CourseMap :EntityTypeConfiguration<Course>  
    {  
       public CourseMap()  
       {  
           //property  
           Property(t => t.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);  
           Property(t => t.Name);  
           Property(t => t.MaximumStrength);             
           Property(t => t.AddedDate).IsRequired();  
           Property(t => t.ModifiedDate).IsRequired();  
           Property(t => t.IP);  
  
           //table  
           ToTable("Courses");            
       }  
    }  
}

现在,我们在 `EF.UnitTest` 项目中创建另一个单元测试类来测试上面的代码。让我们看一下向所有三个表中插入数据的测试方法。

using System;  
using System.Collections.Generic;  
using System.Data.Entity;  
using EF.Core.Data;  
using EF.Data;  
using Microsoft.VisualStudio.TestTools.UnitTesting;  
  
namespace EF.UnitTest  
{  
    [TestClass]  
    public class StudentTest  
    {  
        [TestMethod]  
        public void StudentCourseTest()  
        {  
            Database.SetInitializer<EFDbContext>(new CreateDatabaseIfNotExists<EFDbContext>());  
            using (var context = new EFDbContext())  
            {  
                context.Database.Create();  
                Student student = new Student  
                {  
                    Name = "Sandeep",  
                    Age = 25,  
                    IsCurrent = true,  
                    AddedDate = DateTime.Now,  
                    ModifiedDate = DateTime.Now,  
                    IP = "1.1.1.1",  
                    Courses = new List<Course>{  
                        new Course  
                        {  
                            Name = "Asp.Net",  
                            MaximumStrength = 12,  
                            AddedDate = DateTime.Now,  
                            ModifiedDate = DateTime.Now,  
                            IP = "1.1.1.1"  
                        },  
                         new Course  
                        {  
                            Name = "SignalR",  
                            MaximumStrength = 12,  
                            AddedDate = DateTime.Now,  
                            ModifiedDate = DateTime.Now,  
                            IP = "1.1.1.1"  
                        }  
                    }  
                };  
                Course course = new Course  
               {  
                   Name = "Web API",  
                   MaximumStrength = 12,  
                   AddedDate = DateTime.Now,  
                   ModifiedDate = DateTime.Now,  
                   IP = "1.1.1.1",  
                   Students = new List<Student>{  
                        new Student  
                        {  
                            Name = "Raviendra",  
                            Age = 25,  
                            IsCurrent = true,  
                            AddedDate = DateTime.Now,  
                            ModifiedDate = DateTime.Now,  
                            IP = "1.1.1.1",  
                        },  
                         new Student  
                        {  
                          Name = "Pradeep",  
                        Age = 25,  
                        IsCurrent = true,  
                        AddedDate = DateTime.Now,  
                        ModifiedDate = DateTime.Now,  
                        IP = "1.1.1.1",  
                        }  
                    }  
               };  
                context.Entry(student).State = System.Data.EntityState.Added;  
                context.Entry(course).State = System.Data.EntityState.Added;  
                context.SaveChanges();  
            }  
        }  
    }  
}  

现在运行 `Test` 方法,您将在数据库中看到具有数据的表。在数据库中运行 `select` 查询并获取结果,例如:

SELECT [ID],[Name],[Age],[IsCurrent],[AddedDate],[ModifiedDate],[IP] FROM [EFCodeFirst].[dbo].[Students]  
SELECT [ID],[Name],[MaximumStrength],[AddedDate],[ModifiedDate],[IP] FROM [EFCodeFirst].[dbo].[Courses]  
SELECT [StudentId],[CourseId] FROM [EFCodeFirst].[dbo].[StudentCourse] 

Data for Students and Courses

图 1.7 Students 和 Courses 的数据。

结论

本文介绍了在 Entity Framework Code First 方法中使用 Fluent API 处理关系。我没有在这里使用数据库迁移,因此在运行任何单元测试方法之前,需要删除您的数据库。如果您有任何疑问,请发表评论或直接通过 https://twitter.com/ss_shekhawat 联系。

© . All rights reserved.