码迷,mamicode.com
首页 > 其他好文 > 详细

Programming Entity Framework CodeFirst--表关系约定

时间:2015-03-10 01:23:57      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:

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

    一、一对多

    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; }
}
View Code

  这样,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(200)]
        [MinLength(10)]
        public string Name { get; set; }
        [StringLength(200, MinimumLength = 2)]
        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; }

    }
View Code

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

技术分享

这样就乱掉了。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(50)]
        public string Name { get; set; }
        public List<Trip> Trips { get; set; }
    }

生成了三张表:

技术分享

 进行一个查询:

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; }
    }
View Code

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

 技术分享

 以上都是这一章的笔记。

 园友的同类型博客

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

 

Programming Entity Framework CodeFirst--表关系约定

标签:

原文地址:http://www.cnblogs.com/stoneniqiu/p/4324900.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!