EntityFramework Fluent Api

引用关系

Entity Framework 中配置了对象之间的引用关系后,在查询数据的时候会非常方便。

但是很多老系统中都是没有显示指定外键的,大多是靠在子对象中加一个主对象的 ID 来解决问题。

这时候如果不配置一下的话,是根本无法实现两个对象之间的引用关系的。因为 Entity Framework 并不知道那一列是用来确定引用关系的。

所以,这章将会介绍它默认的规则,也会介绍如何自由地配置引用关系。

默认规则

当你不配置任何东西的时候,Entity Framework 默认会认为你的数据库是这样的:

  • 如果你的实体中有另一个实体的集合类型导航属性,Code First 默认会认为它们是一对多的关系;
  • 如果你的一个实体上有另一个实体的导航属性(不能两者都有对方的导航属性),Code First 也会默认认为它们是一对多的关系;
  • 如果你的两个实体上都有对方的集合类型导航属性,Code First 默认会认为它们是多对多的关系;
  • 如果你的两个实体上都有对方的导航属性,Code First 默认会认为它们是一对一的关系;
  • 默认情况下,Code First 对外键和表名(多对多的关联表)都有要求。

综上:如果你是先建立实体再创建数据库,可以不用配置而使用默认规则;但是如果你是现有数据库,一般很难完全匹配,总会需要配置一些东西。

利用 Fluent API 来配置引用关系

Attribute 配置法(Data Annotations)无法 实现所有功能,建议使用 Fluent API 来实现,具体配置遵循一下标准:

Entity.HasMultiplicity.WithMultiplicity.Map(Option)

其中,Has[Multiplicity] 包含以下三种方法:

  • HasOptional
  • HasRequired
  • HasMany

另外,With[Multiplicity] 同样也包含一下三种方法:

  • WithOptional
  • WithRequired
  • WithMany

最后的 Map 是用来映射外键(非显示外键也行)的。

但是这到底怎么用呢?后面将会用一个实例来演示一下。

配置一对多与一对一关系

public class User
{
    public int ID { get; set; }
    public string Name { get; set; }
    public virtual IList<Article> Articles { get; set; }
}
public class Article
{
    public int ID { get; set; }
    public string Name { get; set; }
    public virtual User Owner { get; set; }
}

上述代码中有两个实体,它们是一对多的关系。

完整的配置代码如下:

public class TestContext : DbContext
{

    public DbSet<User> UserSet { get { return Set<User>(); } }
    public DbSet<Article> ArticleSet { get { return Set<Article>(); } }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder
            .Configurations
            .Add(new UserTypeConfiguration())
            .Add(new ArticleTypeConfiguration());
        base.OnModelCreating(modelBuilder);
    }
}

public class UserTypeConfiguration : EntityTypeConfiguration<User>
{
    public UserTypeConfiguration()
    {
        HasKey(u => u.ID);
        Property(u => u.ID)
            .IsRequired()
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        HasMany(u => u.Articles)
            .WithRequired(a => a.Owner)
            .Map(x => x.MapKey("UserID"));
        ToTable("User");
    }
}
public class ArticleTypeConfiguration : EntityTypeConfiguration<Article>
{
    public ArticleTypeConfiguration()
    {
        HasKey(a => a.ID);
        Property(a => a.ID)
            .IsRequired()
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        ToTable("Article");
    }
}

别的都是基本配置,这里最关键的一段代码是:

HasMany(u => u.Articles)
                .WithRequired(a => a.Owner)
                .Map(x => x.MapKey("UserID"));

其实这里的语义很清晰,如果我把这段英文直接翻译成中文,我觉得可以是这样子的。

“我有许多的 Article,它有一个 Owner 且是必须的,外键被映射成了 UserID”

是不是很清晰的关系?另外,两个实体间的关系只要在任意一个实体上配置一次就行了,但是配置方法不同。

上面是配置在主对象 User 上的,如果配置在 Article 上,语句应该是这样写的:

HasRequired(a => a.Owner)
                .WithMany(u => u.Articles)
                .Map(x => x.MapKey("UserID"));

“我有一个 Owner 切是必须的,它有很多的 Article,外键被映射成了 UserID”

那一对一的关系怎么配置呢?

其实一对一不就是这样的吗:我有一个 XXX,它有一个 XXX,外键被映射成了 XXX。

HasRequired(a => a.Owner)
                .WithOptional(u => u.Article)
                .Map(x => x.MapKey("UserID"));

另外,HasOptional 和 HasRequired 有什么区别呢?区别就在于,这个外键(或非显示外键)是否允许为 Null。

配置多对多关系

多对多关系的语义非常简单:我有很多 XXX,它有很多XXX……

但是,最关键的就是这个 Map。

因为多对多的话,必须要配置一张映射表,具体的配置方法如下:

HasMany(a => a.Categories)
                .WithMany(c => c.Articles)
                .Map(x => x.ToTable("ArticleCategory")
                           .MapLeftKey("ArticleID")
                           .MapRightKey("CategoryID"));

这里在 Map 的时候,必须要配置关联左表的外键(或非显示外键)和关联右表的外键,还要指定关联表的名字。

总体而言,配置起来也非常简单!

时间: 2024-10-14 04:50:12

EntityFramework Fluent Api的相关文章

EntityFramework Code-First 简易教程(七)-------领域类配置之Fluent API

Fluent API配置: 前面我们已经了解到使用DataAnotations特性来覆写Code-First默认约定,现在我们来学习Fluent API. Fluent API是另一种配置领域类的方法,它比DataAnnotations特性提供更多的配置方法,下表是Fluent API支持的类型映射. 映射种类 配置数据库 模型(Model-wide)映射 设置默认架构 设置自定义约定 实体(Entity)映射 设置单表或多表和设置架构 设置复杂类型 设置继承层次结构 属性(Property)映

关于EntityFramework 一对多 Fluent API配置的问题

1.背景 例子:目的地类(Desctination)与客栈(Lodging)的关系是1个目的地可以拥有多个客栈.那么关系就是1对多的关系 2.Code /// <summary> /// 旅游目的地 /// </summary> public class DestinationContract { /// <summary> /// 目的地主键 /// </summary> public long DestinationId { get; set; } //

一步一步学EF系列【2、Fluent API的方式来处理实体与数据表之间的映射关系。】

EF里面的默认配置有两个方法,一个是用Data Annotations(在命名空间System.ComponentModel.DataAnnotations;),直接作用于类的属性上面,还有一个就是Fluent API,通过新增相应的配置类来覆盖默认配置另外.我们主要学习Fluent API,Data Annotations可以自行去学习一下. 补充一下为什么要用Fluent API 使用DataAnnotation非常简单,但对于EntityFramework中的特性,就要在实体类中引入Ent

SimpleReact: 基于Java 8简单的FRP Fluent API

SimpleReact来自AOL的一个小型的支持并发的库包,其直接基于Java 8的CompletableFuture, JDK函数接口和Streams API构建,它的Fluent API能够提供解决90%的Reactive使用场景,重要的是没有带入任何复杂性.可以实现Functional Reactive Programming范式(简称:FRP,函数式响应编程) 使用SimpleReact能够方便扩展微服务,它能用于管理微服务的远程调用,能够应付高并发大型高性能平台的要求. 使用Simpl

使用Fluent API进行实体映射【Code-First系列】

现在,我们来学习怎么使用Fluent API来配置实体. 一.配置默认的数据表Schema Student实体 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EF4 { public class Student { public int StudentID { get; set; } publ

Fluent API in Code-First【Code-First系列】

在前面的章节中,我们已经看到了各种不同的数据注解特性.现在我们来学习一下Fluent API. Fluent API是另外一种配置领域类的方式,它提供了更多的配置相比数据注解特性. Mappings[映射] To Database[转成数据库] Model-wide Mapping[模型映射] Set default Schema[设置默认的Schema] Set Custom Convetions[自定义约定] Entity Mapping[实体映射] To Single or Multipl

关于CodeFirst异常:无法确定类型&#39;XXX&#39;和类型‘YYY’之间的关联的主体端,必须使用关系 Fluent API 或数据注释显式配置此关联的主体端。

此错误的原因是,你配置两个实体间的关系为一对一 然而我认为的一对一关系是,两者之间必须存在一个主体, 也就是说,你不能表1的外键是表2的主键并且表1的主键是表2的外键, 这样不符合数据库式吧? 我想多数人犯这个错误是无意的,并不是想表1的外键是表2的主键并且表1的主键是表2的外键, 怎么改呢?确定主体! 主体就是你要把其他实体的主键存进来的实体. 把非实体的导航属性删除就ok了. 关于CodeFirst异常:无法确定类型'XXX'和类型'YYY'之间的关联的主体端,必须使用关系 Fluent A

Code First 中 Fluent API 的作用

Code First 的使用:http://www.cnblogs.com/sword-successful/archive/2012/12/31/2840391.html(写的很明白) Fluent API 的用法:https://msdn.microsoft.com/zh-cn/data/jj591617.aspx:http://www.dozer.cc/2012/09/entity-framework-code-first-configuring-property/

一起学ASP.NET Core 2.0学习笔记(二): ef core2.0 及mysql provider 、Fluent API相关配置及迁移

不得不说微软的技术迭代还是很快的,上了微软的船就得跟着她走下去,前文一起学ASP.NET Core 2.0学习笔记(一): CentOS下 .net core2 sdk nginx.supervisor.mysql环境搭建搭建好了.net core linux的相关环境,今天就来说说ef core相关的配置及迁移: 简介: Entity Framework(以下简称EF) 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案,EF Core是Entity