表之间的关系分为一对多,多对多,一对一三种,实质就是对外键进行配置。

一、一对多

1. Required

Destination包含Lodging>的集合。

public class Destination
{
public int DestinationId { get; set; }
public string Name { get; set; }
public string Country { get; set; }
public string Description { get; set; }
public byte[] Photo { get; set; }
public List<Lodging> Lodgings { get; set; }
}
public class Lodging
{
public int LodgingId { get; set; }
public string Name { get; set; }
public string Owner { get; set; }
public bool IsResort { get; set; }
public decimal MilesFromNearestAirport { get; set; }
public Destination Destination { get; set; }
}

这样,EF会自动给Lodging表生成外键。Destination_LodgingId.

注意到这个时候Fk,是可以为Null的。修改Lodging,给Destination加上Required。

[Required]
public Destination Destination { get; set; }

再运行

注意到Fk是not null了。

用Api的方式:

modelBuilder.Entity<Destination>().HasMany(d => d.Lodgings).WithOptional(l => l.Destination);

在配置表关系的时候,has方法多是和With方法一起搭配使用。

• HasOptional  //可为null
• HasRequired //不为null
• HasMany //集合

has表示主体对从体的关系。.HasMany(d => d.Lodgings) 表示Destination拥有Lodgings的集合。

• WithOptional //可为null
• WithRequired //不可为null
• WithMany //集合

with表示从体对主体。.WithOptional(l => l.Destination); 表示Lodging的Destination是可以为null的。

可以给Lodging加一个外键。

 public int DestinationId { get; set; }

有了外键,我们赋值的时候附一个id就行了,而不用赋一个对象。

外键DestinationId为非null,是因为他是int型的,如果换成Nullable<int>,数据库会将其设置为可null。

2.Foreignkey

有时候我们属性命名并不规范,如下。这个时候EF就不知道AccommodationId是我们指定的外键如果没有特性[Foreignkey("name")]

[ForeignKey("Accommodation")]
public int AccommodationId { get; set; }
public Lodging Accommodation { get; set; }
//.....或.....
public int AccommodationId { get; set; }
[ForeignKey("AccommodationId")]
public Lodging Accommodation { get; set; }

API:

modelBuilder.Entity<InternetSpecial>().HasRequired(s => s.Accommodation).WithMany(l => l.InternetSpecials)

同样在2中,我们删掉Lodging中的Destination和DestinationId,加上LocationId。

    // public Destination Destination { get; set; }
// public int DestinationId { get; set; }
public int LocationId { get; set; }

要指定LocationId为外键可以:

修改Destination

[ForeignKey("LocationId")]
public List<Lodging> Lodgings { get; set; }

Api:

modelBuilder.Entity<Destination>().HasMany(d => d.Lodgings).WithRequired().HasForeignKey(l => l.LocationId);

3.InverseProperty

再复杂些,Person类拥有两个Lodging集合。

 public class Person
{
public Person()
{
Address=new Address();
Info=new PersonalInfo()
{
Weight = new Measurement(),
Height = new Measurement()
};
} [Key]
public int SocialSecurityNumber { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
public PersonalInfo Info { get; set; }
public Address Address { get; set; }
public PersonPhoto Photo { get; set; }
public List<Lodging> PrimaryContactFor { get; set; }
public List<Lodging> SecondaryContactFor { get; set; }
}
public class Lodging
{
public int LodgingId { get; set; }
[Required]
[MaxLength()]
[MinLength()]
public string Name { get; set; }
[StringLength(, MinimumLength = )]
public string Owner { get; set; }
public bool IsResort { get; set; }
// public Destination Destination { get; set; }
// public int DestinationId { get; set; }
public List<InternetSpecial> InternetSpecials { get; set; }
public Person PrimaryContact { get; set; }
public Person SecondaryContact { get; set; } }

这个时候直接生产的表是:

这样就乱掉了。EF搞不清。需用用InverseProperty告诉它

[InverseProperty("PrimaryContactFor")]
public Person PrimaryContact { get; set; }
[InverseProperty("SecondaryContactFor")]
public Person SecondaryContact { get; set; }

然后生成的外键就干净了。(SocialSecurityNumber是person的主键)

4.级联删除。

在数据库中,因为外键会在实体删除的时候触发级联删除。我们有时候需要配置这个功能关闭。且只有API的方式配置

HasRequired(l=>l.Destination).WithMany(d=>d.Lodgings).WillCascadeOnDelete(false)

如果有多个Required指向同一张表,有的数据库是不支持多个关系的级联删除,这个时候也需要关闭这个功能。

二、多对多

1.Trip和Activity相互包含彼此的集合。

 public class Trip
{
[Key]
public Guid Identifier { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public decimal CostUSD { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
public decimal MilesFromNearestAirport { get; set; } public List<Activity> Activities { get; set; }
}
public class Activity
{
public int ActivityId { get; set; }
[Required, MaxLength()]
public string Name { get; set; }
public List<Trip> Trips { get; set; }
}

生成了三张表:

可以再修改第三张表的表名。TripConfiguration:

HasMany(t => t.Activities).WithMany(a => a.Trips).Map(c => c.ToTable("TripActivities"));

进而也可以修改这个表的键

HasMany(t => t.Activities)
.WithMany(a => a.Trips)
.Map(c =>
{
c.ToTable("TripActivities");
c.MapLeftKey("TripIdentifier");
c.MapRightKey("ActivityId");
});

进行一个查询:

var tripWithActivities = context.Trips.Include("Activities").FirstOrDefault();

三、一对一

如果两个对象,单独相互依赖,这个时候就需要指定谁依赖谁。不然EF不知道就会报错。比如PersonPhoto和Person是一对一的关系。

  public class Person
{
public Person()
{
Address=new Address();
Info=new PersonalInfo()
{
Weight = new Measurement(),
Height = new Measurement()
};
} [Key]
public int SocialSecurityNumber { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
public PersonalInfo Info { get; set; }
public Address Address { get; set; }
public PersonPhoto Photo { get; set; }
public List<Lodging> PrimaryContactFor { get; set; }
public List<Lodging> SecondaryContactFor { get; set; }
}
public class PersonPhoto
{
[Key]
[ForeignKey("PhotoOf")]
public int PersonId { get; set; }
public byte[] Photo { get; set; }
public string Caption { get; set; }
public Person PhotoOf { get; set; }
}

没有[Required]不然会出现下面的错误,EF它不能擅自决定。

以上都是这一章的笔记。

园友的同类型博客

http://www.cnblogs.com/libingql/p/3353112.html

Programming Entity Framework CodeFirst--表关系约定的更多相关文章

  1. 【读书笔记】Programming Entity Framework CodeFirst -- 初步认识

    以下是书<Programming Entity Framework Code First>的学习整理,主要是一个整体梳理. 一.模型属性映射约定 1.通过 System.Component ...

  2. Programming Entity Framework CodeFirst -- 约定和属性配置

     以下是EF中Data Annotation和 Fluenlt API的不同属性约定的对照.   Length Data Annotation MinLength(nn) MaxLength(nn) ...

  3. Programming Entity Framework CodeFirst--数据库约定和配置

    这一章主要主要讲的是我们的模型如何映射到数据库,而不影响模型,以及不同的映射场景. 一.表名和列名 1.指定表名 [Table("PersonPhotos")] public cl ...

  4. Entity Framework Code First关系映射约定

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

  5. Entity Framework Code First关系映射约定【l转发】

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

  6. 第二篇:Entity Framework CodeFirst & Model 映射

    前一篇 第一篇:Entity Framework 简介 我有讲到,ORM 最关键的 Mapping,也提到了最早实现Mapping的技术,就是 特性 + 反射,那Entity Framework 实现 ...

  7. [转]Entity Framework 的实体关系

    通过 Entiy Framework实践系列 文章,理了理 Entity Framework 的实体关系. 为什么要写文章来理清这些关系?“血”的教训啊,刚开始使用 Entity Framework  ...

  8. 第三篇:Entity Framework CodeFirst & Model 映射 续篇 EntityFramework Power Tools 工具使用

    上一篇 第二篇:Entity Framework CodeFirst & Model 映射 主要介绍以Fluent API来实作EntityFramework CodeFirst,得到了大家一 ...

  9. Programming Entity Framework 翻译(2)-目录2-章节

    How This Book Is Organized 本书组织结构 Programming Entity Framework, Second Edition, focuses on two ways ...

  10. [Programming Entity Framework] 第3章 查询实体数据模型(EDM)(一)

    http://www.cnblogs.com/sansi/archive/2012/10/18/2729337.html Programming Entity Framework 第二版翻译索引 你可 ...

随机推荐

  1. 数据库执行sql报错Got a packet bigger than 'max_allowed_packet' bytes及重启mysql

    准备在mysql上使用数据库A,但mysql5经过重装后,上面的数据库已丢失,只得通过之前备份的A.sql重新生成数据库A. 1.执行sql报错 在执行A.sql的过程中,出现如下错误:Got a p ...

  2. PHP的继承方法如何获取子类名

    http://blog.csdn.net/zls986992484/article/details/53154097 PHP后期静态绑定问题:例如 <?php class A { functio ...

  3. Python 第五天 装饰器

    装饰器 装饰器是函数,只不过该函数可以具有特殊的含义,装饰器用来装饰函数或类,使用装饰器可以在函数执行前和执行后添加相应操作. def wrapper(func): def result(): pri ...

  4. depot用例视图建模

    1. 确定系统涉及的内容 图书馆管理系统有以下模块构成:系统登陆模块.图书馆管理模块.学生管理模块.借阅信息管理模块.图书检索模块. 2. 分析系统参与者 确定参与者首先分析系统涉及的问题领域 和 系 ...

  5. lvs DR模式下vip的端口无法telnet

    错误介绍: 在lvs配置文件中新添加一个vip  ,并添加一个virtual_server,添加两个realserver,配置文件都是复制,结果证明没问题,当时的效果是vip的端口telnet不了 过 ...

  6. 高速PCB之EMC设计47则

    高速PCB之EMC设计47则 差模电流和共模电流 辐射产生 电流导致辐射,而非电压,静态电荷产生静电场,恒定电流产生磁场,时变电流既产生电场又产生磁场.任何电路中存在共模电流和差模电流,差模信号携带数 ...

  7. GCD in Swfit 3.0

    这里包括了Queue, Group, Barrier, Semaphore等内容.基本上常用的GCD对象和方法在Swift3.0的改变都囊括其中. 代码在这里:https://github.com/f ...

  8. android 的闪屏效果

    android的闪屏效果,就是我们刚开始启动应用的时候弹出的界面或者动画,过2秒之后自动的跳转到主界面. 其实,实现这个效果很简单,使用Handler对象的postDelayed方法就可以实现.在这个 ...

  9. LR loadrunner参数化-笔记

      LR在录制程序运行的过程中,VuGen(脚本生成器) 自动生成了包含录制过程中实际用到的数值的脚本,如果你企图在录制的脚本中使用不同的数值执行脚本的活动(如查询.提交等等),那么你必须用参数值取代 ...

  10. Ajax异步调用Controller的Return JsonResult生成下拉列表

    @using System.Web.Optimization; @{ Layout = null; } <!DOCTYPE html> <html> <head> ...