2015-04-12 42 views
1

是否可以在數據庫中使用流利的api配置一對一的關係,但不符合約定的要求? 下面我給你的數據庫和生成模型的示例。 請注意,表中沒有定義除主鍵以外的任何約束和索引。如何配置一對一的關係,只使用流利的api而沒有約定

表:從數據庫中生成

create table Person (
    PersonKey int primary key 
) 

create table Address (
    AddressKey int primary key, 
    owner int not null // normally should be foreign key to Person 
) 

代碼首款車型:

public partial class Person 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int PersonKey { get; set; } 
} 

public partial class Address 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int AddressKey { get; set; } 

    public int Owner { get; set; } 
} 

爲了能夠從地址到個人導航,添加導航屬性到Address類:

public partial class Address 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int AddressKey { get; set; } 

    public int Owner { get; set; } 

    public virtual Person Person { get; set; } 
} 

如果程序嘗試執行此查詢:

var Addresss = context.Addresss.Include(x => x.Person).ToList(); 

運行時引發異常:「無效的列名'Person_PersonKey'」。由於上下文不配置任何自定義映射,它會嘗試通過約定來查找外鍵,但所有者屬性不符合約定要求,因此是例外。所以需要添加映射。 如果Person和Address之間的關係是一對多,我們可以添加這樣的配置:以上定義

modelBuilder.Entity<Address>() 
      .HasOptional(x => x.Person) 
      .WithMany() 
      .HasForeignKey(x => x.Owner); 

及查詢將正確執行。但是,如果Person類會有什麼導航財產地址,以便我們將有雙向的一對一的關係:

public partial class Person 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int PersonKey { get; set; } 

    public virtual Address Address { get; set; } 
} 

所以上述的配置將無法工作,我的問題是,是否有可能將其配置在不改變DB和財產名稱,如果是,哪些配置需要使用流利的API才能應用?

+0

沒有約定的意思? – renakre

+0

這意味着您的POCO不遵循EF默認約定。 – tgrabus

+0

這意味着POCO不遵循EF默認約定,所以您需要使用屬性或流利API來將POCO映射到db中正確的表和列。 正如您在Person類中所看到的那樣,它具有PersonKey屬性而不是PersonId,並且需要使用Key屬性標記以知道它是主鍵。如果沒有這個屬性,它會拋出異常。 – tgrabus

回答

0

這是我的建議代碼,我希望我正確理解你!

public partial class Person 
{ 
    public int PersonKey { get; set; } 

    public Address Address {get;set;} 
} 

public partial class Address 
{ 
    public virtual Person Person { get; set; } 

    public int PersonId { get; set; } 

    public string AddressInfo {get;set;} 
} 

modelBuilder.Entity<Person>() 
      .HasKey(a => a.PersonKey); 

modelBuilder.Entity<Course>() 
      .Property(c => c.CourseId) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 

modelBuilder.Entity<Address>() 
      .HasKey(a => a.PersonId); 

modelBuilder.Entity<Person>() 
      .HasRequired(p => p.Address) 
      .WithRequiredPrincipal(a => a.PersonId); 
+0

不幸的是,這是行不通的。定義一對一關係時,HasForeignKey不可訪問。除此之外,您在Person導航屬性上使用ForeignKey屬性,但我不需要它。我只想用流利的API解決問題。 – tgrabus

相關問題