一、Has方法与With方法如:A类必须包含B类一个不为null的实例,而B类可选择时候包含A类一个实例。 A.HasRequired(a => a.B).WithOptional(b => b.A);1、Has方法:
2、With方法:
二、一对一关系:两个类中先都要配置相应的引用属性 1、DataAnnotations数据标注的方式用到ForeignKey外键标注。 public class Person{ public int PersonId { get; set; } public int SocialSecurityNumber { get; set; } public string FirstName { get; set; } public string LastName { get; set; } [Timestamp] public byte[] RowVersion { get; set; } public PersonPhoto Photo { get; set; } } public class PersonPhoto { [Key, ForeignKey("PhotoOf")] //注意:PersonPhoto表中的PersonId既是外键也必须是主键 public int PersonId { get; set; } public byte[] Photo { get; set; } public string Caption { get; set; } public Person PhotoOf { get; set; } } 2、Fluent API方式(1)1:0..1关系PersonPhoto必须属于一个Person,但是Person不一定有PersonPhoto, 此种情况下Person是一定存在的,所以它是主从关系主的一方。 modelBuilder.Entity<Person>().HasOptional(t => t.Photo).WithRequired(t => t.PhotoOf);modelBuilder.Entity<PersonPhoto>().HasRequired(p => p.PhotoOf).WithOptional(p => p.Photo); (2)1:1 关系PersonPhoto必须属于一个Person,Person也必须有PersonPhoto。 modelBuilder.Entity<Person>().HasRequired(p => p.Photo ).WithRequiredPrincipal();modelBuilder.Entity<PersonPhoto>().HasRequired(t => t.PhotoOf).WithRequiredDependent(t => t.Photo); 此种情况下,两个都一定存在,要确定主从关系,需要使用WithRequiredPrincipal或WithRequiredDependent。
三、一对多关系:1、DataAnnotations方式一对多关系很多情况下我们都不需要特意的去配置,通过一些引用属性、导航属性等检测到模型之间的关系,自动为我们生成外键。 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 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 Target { get; set; } } Code First观察到Lodging类中有一个对Destination的引用属性,或者Destination中又有一个集合导航属性Lodgings,因此推测出Destination与Lodging的关系是一对多关系. 所以在生成的数据库中为自动为Lodging表生成外键:外键名:Target_DestinationId 2、更改外键的nullable属性和外键的名字默认情况下,如果你的外键命名是规范的话,Code First自动会将该属性设置为外键,不再自动创建一个外键。
如:DestinationId属性自动作为主键。 public class Lodging{ public int? DestinationId { get; set; } public Destination Destination { get; set; } } 当然我们也可以自己在类中增加一个外键。 1、使用Data Annotations指定外键:注意ForeignKey位置的不同,其后带的参数也不同。 [ForeignKey("Target")]public int TarDestinationId { get; set; } public Destination Target { get; set; } 或 public int TarDestinationId { get; set; }[ForeignKey("TarDestinationId")] public Destination Target { get; set; } 2、用Fluent API指定外键:如果实体类没定义AccommodationId,那么可以使用Map方法直接指定外键名:.Map(s => s.MapKey("AccommodationId")) modelBuilder.Entity<Lodgings>().HasRequired(l => l.Target).WithMany(d=>d.Lodgings).HasForeignKey(l => l.TarDestinationId); (2)Post可以单独存在,不用归属于Blog,这种关系是0..1:n。 modelBuilder.Entity<Destination>().HasMany(d => d.Lodgings).WithOptional(l => l.Destination).Map(l => l.MapKey("DestinationId"));modelBuilder.Entity<Lodgings>().HasOptional(l => l.Target).WithMany(d => d.Lodgings).HasForeignKey(l => l.TarDestinationId); 3、对同一实体多个引用的情况public class Person{ public int PersonID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public List PrimaryContactFor { get; set; } public List SecondaryContactFor { 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 Target { get; set; } //第一联系人 public Person PrimaryContact { get; set; } //第二联系人 public Person SecondaryContact { get; set; } } Lodging(旅店)有两个对Person表的引用,分别是PrimaryContact与SecondaryContact, 因为在这两个表之间存在多个一对多关系,所以Code First无法处理这种情况。 (1)使用Data Annotations: //第一联系人[InverseProperty("PrimaryContactFor")] public Person PrimaryContact { get; set; } //第二联系人 [InverseProperty("SecondaryContactFor")] Person SecondaryContact { get; set; } (2)或使用Fluent API: modelBuilder.Entity<Lodging>().HasOptional(l => l.PrimaryContact).WithMany(p => p.PrimaryContactFor);modelBuilder.Entity<Lodging>().HasOptional(l=>l.SecondaryContact).WithMany(p=>p.SecondaryContactFor)).Map(p => p.MapKey("SecondaryPersonID "));; 在生成的数据库中为自动为Lodging表生成两个外键:PrimaryContact _PersonID 和SecondaryPersonID 4、级联删除1、如果两个表之间存在一对多关系,Code First默认会开启两个表之间的级联删除功能 .WillCascadeOnDelete(false); // 关闭级联删除 2、也可以在上下文的OnModelCreating方法中移除这个默认约定 modelBuilder.Conventions.Remove();再需要开启级联删除,则可以在FluentAPI关系映射中用. WillCascadeOnDelete(true) 单独开启 四、多对多关系如果有两个类中,各自都是导航属性指向另一个类,Code First会认为这两个类之间是多对多关系,例如: public class Trip{ public int TripId { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public decimal CostUSD { get; set; } public byte[] RowVersion { get; set; } public List Activities { get; set; } } public class Activity { public int ActivityId { get; set; } [Required, MaxLength(50)] public string Name { get; set; } public List Trips { get; set; } } Code First生成了一张中间表ActivityTrips,将另外两张表的主键都作为外键关联到了中间表上面。 指定表名如果我们想指定中间表的名称和键名称,我们可以用Fluent API来配置。 modelBuilder.Entity<Trap>().HasMany(t => t.Activities).WithMany(a => a.Trips).Map(m =>{ m.ToTable("TripActivities"); m.MapLeftKey("TripIdentifier");//对应Trip的主键 m.MapRightKey("ActivityId"); }); //或者 modelBuilder<Activity>.Entity().HasMany(a => a.Trips).WithMany(t => t.Activities).Map(m => { m.ToTable("TripActivities"); m.MapLeftKey("ActivityId");//对应Activity的主键 m.MapRightKey("TripIdentifier"); }); 到此这篇关于Entity Framework配置关系的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。 |
本文实例为大家分享了C# GDI+实现时钟表盘的具体代码,供大家参考,具体内容如下一、...
目录一、正则表达式应用举例1、C#校验合法性:2、C#限制输入3、正则表达式匹配闭合HTM...
本文实例为大家分享了C#实现图形界面的时钟的具体代码,供大家参考,具体内容如下秒针...
目录一、ObjectContext对象上下文1、ObjectContext和DbContext的对比2、ObjectContext...
IronPython是一种在 .NET及 Mono上的 Python实现,由微软的 Jim Hugunin所发起,是一...
本文实例为大家分享了使用C#写一个时钟,供大家参考,具体内容如下时钟是这样的一共使...
一、介绍Topshelf是一个开源的跨平台的宿主服务框架,支持Windows和Mono,只需要几行...
本文实例为大家分享了C#实现动态数字时钟和日历的具体代码,供大家参考,具体内容如下...