如何在实体框架中使用fluent api为一对零.one关系指定外键属性



我有一个表User和另一个表Company。一个User可以注册零家公司,也可以注册一家公司。

User (1)---> (0..1) Company

我的用户类别:

public class User {
public string Id {get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName
{
get { return FirstName + " " + LastName; }
}
//Relations
public virtual Company Company { get; set; }
}

我的公司等级是:

public class Company {
public int Id { get; set; }        
public string CompanyName { get; set; }
public string TaxNumber { get; set; }
public string TaxOffice { get; set; }
public string OfficeTel { get; set; }
public string FaxNumber { get; set; }
public string WebSite { get; set; }
public string Address { get; set; }
public string About { get; set; }
//keys
public int CityId { get; set; }
public int StateId { get; set; }                
public string UserId { get; set; }
//relations
public City City { get; set; }
public State State { get; set; }        
public User User { get; set; }
}

公司使用的fluent api是这样的:

public class CompanyConfiguration : EntityTypeConfiguration<Company>
{
public CompanyConfiguration()
{
this.HasRequired(x => x.User)
.WithOptional(x => x.Company);
this.HasRequired(x => x.City)
.WithMany(x => x.Companies).HasForeignKey(x => x.CityId).WillCascadeOnDelete(false);
this.HasRequired(x => x.State)
.WithMany(x => x.Companies).HasForeignKey(x => x.StateId).WillCascadeOnDelete(false);
this.Property(x => x.Address).HasMaxLength(400);
this.Property(x => x.CompanyName).HasMaxLength(100).IsRequired();
this.Property(x => x.FaxNumber).HasMaxLength(20);
this.Property(x => x.OfficeTel).HasMaxLength(20);
this.Property(x => x.TaxNumber).HasMaxLength(20).IsRequired();
this.Property(x => x.TaxOffice).HasMaxLength(50).IsRequired();
this.Property(x => x.WebSite).HasMaxLength(200);            
}
}

在我运行Add-Migration之后,我希望UserIdCompany表中用作User的外键,但实体框架迁移生成的是:

CreateTable(
"dbo.Companies",
c => new
{
Id = c.Int(nullable: false, identity: true),
CompanyName = c.String(nullable: false, maxLength: 100),
TaxNumber = c.String(nullable: false, maxLength: 20),
TaxOffice = c.String(nullable: false, maxLength: 50),
OfficeTel = c.String(maxLength: 20),
FaxNumber = c.String(maxLength: 20),
WebSite = c.String(maxLength: 200),
Address = c.String(maxLength: 400),
About = c.String(),
CityId = c.Int(nullable: false),
StateId = c.Int(nullable: false),
UserId = c.String(),
User_Id = c.String(nullable: false, maxLength: 128),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.Cities", t => t.CityId)
.ForeignKey("dbo.States", t => t.StateId)
.ForeignKey("dbo.AspNetUsers", t => t.User_Id)
.Index(t => t.CityId)
.Index(t => t.StateId)
.Index(t => t.User_Id);

问题是,我如何强制Entity Framework使用我指定的属性作为关系的外键,原因是我在代码中经常需要一个公司的userId值,而我不想使用Company.User.Id表达式来获得它。

注:我使用实体框架6.1.2和asp.net mvc 5

以下是我如何定义这种关系中的外键:

public class Company {
public int Id { get; set; }        
[Required]
[Key, ForeignKey("User")]
public string UserId { get; set; }       
public User User { get; set; }
}

聚会有点晚了,但我只是想一想,以防其他人遇到这个问题。

我自己也有同样的问题,实体框架(EF6)似乎没有为1-2-0/1关系指定外键的方法,但重要的是要记住,如果需要,它被设计为覆盖。我可以配置它的唯一方法是手动修改自动生成的迁移文件。

示例以下是自动生成的迁移代码的缩写版本(如上所述),显示了原本要作为FK的UserId和EF插入的自动添加的属性User_Id

CreateTable(
"dbo.Companies",
c => new
{
Id = c.Int(nullable: false, identity: true),
...
UserId = c.String(),
User_Id = c.String(nullable: false, maxLength: 128),
})
.PrimaryKey(t => t.Id)
...
.ForeignKey("dbo.AspNetUsers", t => t.User_Id)
...
.Index(t => t.User_Id);

为了实现UserId作为FK的初衷,只需删除自动生成的属性,然后修改FK语句和索引语句

CreateTable(
"dbo.Companies",
c => new
{
Id = c.Int(nullable: false, identity: true),
...
UserId = c.String(nullable: false, maxLength: 128),
})
.PrimaryKey(t => t.Id)
....
.ForeignKey("dbo.AspNetUsers", t => t.UserId)
...
.Index(t => t.UserId);

NB问题中未显示恢复迁移的Down方法,但对Up方法所做的任何添加或修改也需要反映在Down方法中。

相关内容

  • 没有找到相关文章

最新更新