2013-07-30 103 views
1

沒有一個類似的問題似乎能夠解決這個問題。我正在使用實體框架5,MVC 4,.NET 4.5爲我的web應用程序,設計與VS 2012.Code First EF5:一對零或一對一關係不起作用

我有2類應該是在父子關係。

[Table("UserProfile")] 
public class UserProfile 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int UserId { get; set; } 

    // Other stuff 

    public int? JoggerId { get; set; } 
    public virtual Jogger Jogger{ get; set; } 
} 

public class Jogger 
{ 
    [Key] 
    public int JoggerId { get; set; } 

    [Required, ForeignKey("UserId")] 
    public int UserId { get; set; } 
    public virtual UserProfile UserProfile { get; set; } 
} 

隨着流利API:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 

     modelBuilder.Entity<UserProfile>() 
      .HasOptional(x => x.Jogger) 
      .WithRequired(c => c.UserProfile) 
      .WillCascadeOnDelete(true); 

     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
     base.OnModelCreating(modelBuilder); 
    } 

用戶可以是一個齊紙機也不能是慢跑即一個用戶到零個或一個齊紙機。 EF Powertools edmx視圖中的關係看起來不錯,但我無法使用外鍵與UserProfile UserId一起使用。

是我的Fluent API錯誤還是我的模型?請幫助 - 我真的被卡住了!

回答

3

你用流利的API映射是確定的,但是從你的模型中刪除UserProfile.JoggerIdJogger.UserId性質,它應該工作。原因是Entity Framework使用Jogger的主鍵作爲UserProfile的外鍵,因此您不需要(也不能)具有單獨的外鍵屬性。這種一對一的關係被稱爲「Shared Primary Key Association」。

編輯

記住的Jogger主鍵(如從屬關係)是在數據庫中自動生成,只有UserProfile主鍵自動生成(作爲主關係)。

你會怎麼插入UserProfileJogger或兩個到數據庫的方式如下:

  • 如果要插入一個UserProfile沒有Jogger只需將其添加到上下文:

    using (var context = new MyContext()) 
    { 
        var newUserProfile = new UserProfile(); 
        // no key needs to be supplied, the DB will take care 
    
        context.UserProfiles.Add(newUserProfile); 
        context.SaveChanges(); 
    } 
    
  • 如果你想在一個步驟插入一個Jogger一個UserProfile

    using (var context = new MyContext()) 
    { 
        var newUserProfile = new UserProfile { Jogger = new Jogger() }; 
        // no key needs to be supplied, neither for UserProfile 
        // nor for Jogger, the DB will take care 
    
        context.UserProfiles.Add(newUserProfile); 
        context.SaveChanges(); 
    } 
    
  • 如果要插入一個Jogger(和它必須是一個現有的UserProfile一個Jogger):

    using (var context = new MyContext()) 
    { 
        var newJogger = new Jogger { JoggerId = someExistingUserProfileId }; 
        // a valid key needs to be supplied, otherwise you would violate a FK 
        // constraint in the database 
    
        context.Joggers.Add(newJogger); 
        context.SaveChanges(); 
    } 
    

編輯2

爲您的使用情況你沒有UserId直接可用,但Name(作爲身份驗證用戶),而不是你必須加載鍵或從數據庫中第一UserProfile

// we are in an ASP.NET MVC controller action here 
using (var context = new MyContext()) 
{ 
    string userName = User.Identity.Name; 
    int? userId = context.UserProfiles 
     .Where(u => u.Name == userName) 
     .Select(u => (int?)u.UserId) 
     .SingleOrDefault(); 

    if (userId.HasValue) 
    { 
     var newJogger = new Jogger { JoggerId = userId.Value }; 
     context.Joggers.Add(newJogger); 
     context.SaveChanges(); 
    } 
} 

或加載的UserProfile也能發揮作用:

using (var context = new MyContext()) 
{ 
    string userName = User.Identity.Name; 
    UserProfile userProfile = context.UserProfiles 
     .Where(u => u.Name == userName) 
     .SingleOrDefault(); 

    if (userProfile != null) 
    { 
     userProfile.Jogger = new Jogger(); 
     // I believe you don't need to set the JoggerId key now, 
     // I'm not sure though 

     context.SaveChanges(); 
     // Change tracking recognizes the new Jogger 
     // no context.Joggers.Add is required 
    } 
} 
+0

謝謝Slauma。我試過這個,id已經解決了,但是在id值沒有更新的時候出現了同樣的錯誤。 'INSERT語句與FOREIGN KEY約束「UserProfile_Jogger」衝突。數據庫「aspnet-20130725111018」,表「dbo.UserProfile」,列'UserId'發生衝突。 該聲明已被終止。'當我添加一個用戶的完美,但是當我添加慢跑者配置文件時,它會中斷。欣賞協助。 Springbokkie – Springbokkie

+0

@Springbokkie:'Jogger'是依賴於'UserProfile'的實體。當你添加一個'Jogger'時,你必須將其關鍵屬性'JoggerId'設置爲一個有效的現有'UserProfile'鍵。 JoggerId不是數據庫生成的密鑰,因此您必須手動提供值。 – Slauma

+0

謝謝。我是否修改慢跑者課程JoggerId {get;設置{= UserProfile.UserId};}或者我將它設置爲創建?如果在課堂上設置,請告訴我使用什麼代碼。對不起 - 我真的很新鮮。 – Springbokkie