Programming Entity Framework CodeFirst--表关系约定
表之间的关系分为一对多,多对多,一对一三种,实质就是对外键进行配置。
一、一对多
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--表关系约定的更多相关文章
- 【读书笔记】Programming Entity Framework CodeFirst -- 初步认识
以下是书<Programming Entity Framework Code First>的学习整理,主要是一个整体梳理. 一.模型属性映射约定 1.通过 System.Component ...
- Programming Entity Framework CodeFirst -- 约定和属性配置
以下是EF中Data Annotation和 Fluenlt API的不同属性约定的对照. Length Data Annotation MinLength(nn) MaxLength(nn) ...
- Programming Entity Framework CodeFirst--数据库约定和配置
这一章主要主要讲的是我们的模型如何映射到数据库,而不影响模型,以及不同的映射场景. 一.表名和列名 1.指定表名 [Table("PersonPhotos")] public cl ...
- Entity Framework Code First关系映射约定
本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...
- Entity Framework Code First关系映射约定【l转发】
本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...
- 第二篇:Entity Framework CodeFirst & Model 映射
前一篇 第一篇:Entity Framework 简介 我有讲到,ORM 最关键的 Mapping,也提到了最早实现Mapping的技术,就是 特性 + 反射,那Entity Framework 实现 ...
- [转]Entity Framework 的实体关系
通过 Entiy Framework实践系列 文章,理了理 Entity Framework 的实体关系. 为什么要写文章来理清这些关系?“血”的教训啊,刚开始使用 Entity Framework ...
- 第三篇:Entity Framework CodeFirst & Model 映射 续篇 EntityFramework Power Tools 工具使用
上一篇 第二篇:Entity Framework CodeFirst & Model 映射 主要介绍以Fluent API来实作EntityFramework CodeFirst,得到了大家一 ...
- Programming Entity Framework 翻译(2)-目录2-章节
How This Book Is Organized 本书组织结构 Programming Entity Framework, Second Edition, focuses on two ways ...
- [Programming Entity Framework] 第3章 查询实体数据模型(EDM)(一)
http://www.cnblogs.com/sansi/archive/2012/10/18/2729337.html Programming Entity Framework 第二版翻译索引 你可 ...
随机推荐
- jQuery简介
jQuery简介 jQuery是继Prototype之后的又一个javascript库,它由John Resig创建于2006年1月. Javascript库作用比较: 1. Prototype(ht ...
- postgreSQL 统计语句
pg_stat_statements 是 postgresql 的一个扩展,用来统计查询语句,类似于 mysql 的 慢查询. 安装二进制文件 有些发行版可能没有附带这个扩展,则需要用户自己安装, 本 ...
- 【安卓安全】ARM平台代码保护之虚拟化
简介:代码的虚拟化即不直接通过CPU而是通过虚拟机来执行虚拟指令.代码虚拟化能有效防止逆向分析,可大大地增加了代码分析的难度和所需要的时间,若配合混淆等手段,对于动静态分析有着较强的防御能力. 背景: ...
- UIActivityIndicatorViewStyle
UIActivityIndicatorView *indicatorV = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyl ...
- OD使用教程5
怎样恢复数据被改过的代码 点击m进入内存分布图 双击进入文件头 将过大的值一一修改为正常值 普通程序没有动态链接表所以值改为0 保存:首先记住地址 其次 选中差不多的长度,保存 正常的程序
- HttpWebRequest header configuration
more details: http://www.cnblogs.com/yczz/archive/2012/06/01/2530484.html 在HttpWebRequest中,有一些header ...
- PHP那些非常有用却鲜有人知的函数
PHP里有非常丰富的内置函数,很多我们都用过,但仍有很多的函数我们大部分人都不熟悉,可它们却十分的有用.这篇文章里,我列举了一些鲜为人知但会让你眼睛一亮的PHP函数. levenshtein() 你有 ...
- Win7 64位 VS2013环境编译Lua5.3.1
主要参考这篇文章,原文有几个错误顺便改正了. 在Windows下使用Visual Studio编译Lua5.3 写本文时Lua官方网站放出的新版本为5.3.1,然后我不知道为啥,神奇的国内不能访问Lu ...
- struts2是如何加载相关的package元素节点信息的
这不是一篇纯技术文章,而是一篇分享我个人在前后端分离路上收获的点点滴滴的文章,以此来为准备尝试前后端分离或者想了解前后端分离的童鞋做一个大体的讲解. 上一家公司是家小公司,做了一年的全栈开发,对前端的 ...
- 谈FME批量自动化数据转换方法
FME作为转换神器,支持几百种格式的互转,实现互操作化.从fme.exe执行方式入手,讨论Command命令式执行模板(.fmw/.fmwt)和脚本(.tcl/.py)实现自动化批量转换. 1.fme ...