这一篇说说 EF Fluent API 和 DataAnnotations

参考 :

http://msdn.microsoft.com/en-us/data/jj591617.aspx

http://msdn.microsoft.com/en-us/data/jj591620.aspx

Fluent API 和 DataAnnotations 主要作用是让我们定义数据库映射的关系还有一些比如名字不相等的情况等等。

关系数据库一般我们有 1对1,1对多,多对多的表关系

下面我们来一一列出

注 : 这里的思想是先有表,才有类,这里只是例子,真真开发的时候通常是建类图才建数据库的。

我给一个电子商务的案子

我们有个产品种类的表 (prod_category) 还有一个产品表 (prod) , 1个产品可以在多个种类中出现,1个种类也可以有多个产品,所以他们的关系是 (多对多)

所以呢,我们得要多一个表来维持它们的关系,就叫 prod_category_vs_prod 表吧.

prod_category表

[Table("prod_category")] //使用标签,我们可以修改表名
public class ProdCategory
{
[Key] //标签Key,代表id 是主键
public Int32 id { get; set; }
public string category { get; set; } //种类名字 public virtual ICollection<Prod> prods { get; set; } //一个种类有多个产品,所以这里是个 collection , 记得是virtual哦,原理以后会解释.
}

prod表

[Table("prod")]
public class Prod
{
[Key]
public Int32 id { get; set; }
public string code { get; set; }
public string name { get; set; }
public virtual ICollection<ProdCategory> categorys { get; set; } //这里也可以反向获取到种类集合,一个产品有很多种类
}

好,那我们来定义关系

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Prod>()
.HasMany(prod => prod.categorys) //prod 有很多 categorys
.WithMany(category => category.prods) //category 也有很多prods
.Map(m =>
{
m.ToTable("prod_category_vs_prod");
m.MapLeftKey("prod_category_id");
m.MapRightKey("prod_id");
});
}

.Map 记入了维护它们之间的关系表,也就是 prod_category_vs_prod 建对建

好,接着是 1对0,或1对1 关系

这里想不出特别好的例子,我们假设一个产品有一个或没有细节

细节被记入在一个 prod_detail 表中

[Table("prod_detail")]
public class ProdDetail
{
[Key]
public Int32 id { get; set; }
public string fullDescription { get; set; }
[Column("prod_id")] //用标签需改column名
public Int32 prodId { get; set; } //这个是外键 public virtual Prod prod { get; set; } //一个detail肯定有一个prod
}
    [Table("prod")]
public class Prod
{
[Key]
public Int32 id { get; set; }
public string code { get; set; }
public string name { get; set; } public virtual ProdDetail detail { get; set; } //这里有一个detail,但有可能是null
public virtual ICollection<ProdCategory> categorys { get; set; }
}
1-0
modelBuilder.Entity<ProdDetail>()
.HasKey(detail => detail.prodId); //一对一,所以prodId也算是主键
modelBuilder.Entity<ProdDetail>()
.HasRequired(detail => detail.prod) //detail 一定有 prod
.WithOptional(prod => prod.detail); //prod 不一定有 detail //1 -1
modelBuilder.Entity<ProdDetail>()
.HasKey(detail => detail.prodId); //也算主键
modelBuilder.Entity<Prod>()
.HasRequired(prod => prod.detail) //prod 一定有 detail
.WithRequiredPrincipal(detail => detail.prod); detail 也一定有 prod

最后是1对多关系

比如1个产品有很多颜色

就一个 prod_color表吧

    [Table("prod_color")]
public class ProdColor
{
[Key]
public Int32 id { get; set; }
public string color { get; set; }
[Column("prod_id")]
public Int32 prodId { get; set; } public virtual Prod prod { get; set; } //一定有prod
}

直接上关系代码

//1-n
modelBuilder.Entity<ProdColor>()
.HasRequired<Prod>(color => color.prod) //color 一定有 prod
.WithMany(prod => prod.colors) //prod 有很多 colors 
.HasForeignKey(color => color.prodId); //color 有一个外键 prodId

modelBuilder.Entity<Prod>()
.HasMany<ProdColor>(prod => prod.colors) //prod 有很多 colors 
.WithRequired(color => color.prod) //color 一定有 prod 
.HasForeignKey(color => color.prodId); //color 有外键 prodId

好啦,大致上是这样先。

其实 1-0|1, 1-n 都可以直接用 DataAnnotations 来完成,并不需要用 Fluent API .

只是多对多的关系好像不行,所以呢

其实2个都应该学会,我个人是觉得如果只用标签来描述全部东西也是有点乱,

所以呢,关系就用 Fluent API , 如果是表名字,类型,maxlength, primary key 等等可以用标签来完成。这样分担工作就不乱了咯!

这里给出常用的整理版本

1-1 关系

//DataAnnotation 1-1 table
//SQLtable : member , columns : memberId, name
[Table("member")]
public class Member
{
[Key]
public Int32 memberId { get; set; }
public string name { get; set; }
[Required] //1-1关系最好是放啦
public virtual Address address { get; set; }
}
//SQLtable : address , columns : memberId, postcode, country
[Table("address")]
public class Address
{
[Key, ForeignKey("member")] //关键就是这个关系连接, "member" 是 tableName
public Int32 memberId { get; set; } //这里写addressId 也行
public string postcode { get; set; }
public string country { get; set; }
public virtual Member member { get; set; }
}

Entity Framework with MySQL 学习笔记一(关系)的更多相关文章

  1. Entity Framework with MySQL 学习笔记一(关系整理版)

    1-1 设置 //DataAnnotation 1-1 | 1-0 table //SQLtable : member , columns : memberId, name //SQL basic l ...

  2. Entity Framework with MySQL 学习笔记一(安装)

    声明 :  数据库是Mysql,本人的程度只到会写sql语句(不会储蓄过程), c# 会基本的ADO.NET数据库访问,LINQ基础. 这篇只做个人学习|温习作用. 新手可以参考,也请高手指正错误, ...

  3. Entity Framework with MySQL 学习笔记一(查看EF和SQL请求日志)

    做数据库的一向来都会很注意请求的次数还有语句.这关系到很多性能的问题. 因此在使用EF的时候如果不了解原理很可能会搞出很糟糕的请求. 所以呢,在还没有搞懂EF前最基本的是你得"看得见&quo ...

  4. Entity Framework with MySQL 学习笔记一(乐观并发)

    在做项目时,通常我们对乐观并发有几种处理模式 1. 告诉用户此数据已被其他人捷足先登,更改了.你就算新一下重来吧. 2.直接把数据覆盖上去,我最大. 3.用被人的数据. 这里给出 code first ...

  5. Entity Framework with MySQL 学习笔记一(继承)

    基本上sql中要表示继承关系有3中方式. 分别是,1表继承(TPH),2表继承(TPC),3表继承(TPT) 1表 : Person id type name classroom office 1 s ...

  6. Entity Framework with MySQL 学习笔记一(insert,update,delete)

    先说说 insert 吧. 当EF执行insert时,如果我们传入的对象是有关联(1对多等)的话,它会执行多个语句 insert到多个表, 并且再select出来填充我们的属性(因为有些column默 ...

  7. Entity Framework with MySQL 学习笔记一(拦截)

    参考 : http://msdn.microsoft.com/en-us/data/dn469464.aspx EF 允许我们在发送SQL请求和返回数据时做一些拦截的动作 比如可以自定义写 log , ...

  8. Entity Framework with MySQL 学习笔记一(验证标签)

    直接上代码 [Table("single_table")] public class SingleTable { [Key] public Int32 id { get; set; ...

  9. Entity Framework with MySQL 学习笔记一(复杂类型 Complex Types)

    有时候我们希望在sql一个表里面的column, 一部分被分化成另一个class 典型的例子是 Address 直接看代码: [Table("member")] public cl ...

随机推荐

  1. C++类型转换[转]

    转自 http://www.cnblogs.com/goodhacker/archive/2011/07/20/2111996.html C风格的强制类型转换(Type Cast)很简单,不管什么类型 ...

  2. 微信公众账号【iOSDevTip】推出新栏目【看大牛】

    首先你须要关注微信公众账号[iOSDevTip] 基于微信公众平台数据分析.非常easy发现.移动端project师都喜欢关注互联网创业资讯.都说.一个不关注互联网创业的iOS开发不是一个合格的互联网 ...

  3. Windows 驱动开发 - 5

    上篇<Windows 驱动开发 - 4>我们已经完毕了硬件准备. 可是我们还没有详细的数据操作,比如接收读写操作. 在WDF中进行此类操作前须要进行设备的IO控制,已保持数据的完整性. 我 ...

  4. java接口与抽象类的区别

    接口可以是标志接口,里面没有任何常量和方法. 抽象类不一定必须有抽象方法,也可也没有方法,但含抽象方法的类必须被声明为抽象类. 在抽象层次结构中,Java接口在最上面,然后紧跟着抽象类,然后是一般类. ...

  5. B/S架构的几种形式

    1. 什么是B/S架构 B/S架构的全称为Browser/Server,即浏览器/服务器结构.Browser指的是Web浏览器,极少数事务逻辑在前端实现,但主要事务逻辑在服务器端实现.B/S架构的系统 ...

  6. 使用solr报错,错误信息 include(SolrClient.php): failed to open stream: No such file or directory

    这个是因为本地没有安装php-solr的扩展导致的,安装方法(使用的是ubuntu) cd /optwget http://pecl.php.net/get/solr-1.0.2.tgztar -xv ...

  7. Ubuntu启动时直接进入命令行模式

    直接粘命令吧 sudo vim /etc/init/lightdm.conf 注释掉下面的内容 start on ((filesystem and runlevel [!06] and started ...

  8. CSS元素分类及区别

    元素是文档结构的基础,在CSS中,每个元素生成了一个包含了元素内容的框(box,也译为“盒子”).但是不同的元素显示的方式会有所不同,例如<div>和<span>就不同,而&l ...

  9. rpm命令数据库修复日志

    今天在linux安装软件过程中遇到了一个小坑,rpm数据库被破坏: 状况: #rpm -qa | grep rpm 返回: [解决方案] 删除旧数据库,然后重建数据库: 删除旧数据库: # rm /v ...

  10. Android开发手记(9) DatePickerDialog 和 TimePickerDialog

    1.DatePickerDialog  用于获取用户输入的日期信息.其原型为: public DatePickerDialog(Contex contex, DatePickerDialog.OnDa ...