簡體   English   中英

Code First EF5:One-to-Zero-One關系不起作用

[英]Code First EF5: One-to-Zero-or-One relationship is not working

類似的問題似乎都無法解決這個問題。 我正在使用Entity Framework 5,MVC 4,.NET 4.5作為我的Web應用程序,使用VS 2012設計。

我有兩個應該是親子關系的課程。

[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; }
}

使用Fluent 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視圖中的關系看起來很好,但是我無法使用Foreign鍵來使用UserProfile UserId。

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

使用Fluent API進行映射是可以的,但是從模型中刪除UserProfile.JoggerIdJogger.UserId屬性應該可以正常工作。 原因是Entity Framework使用Jogger的主鍵作為UserProfile的外鍵,因此您不需要(也不能)具有單獨的外鍵屬性。 這種一對一的關系稱為“ 共享主鍵關聯 ”。

編輯

請記住, Jogger的主鍵(作為關系的依賴) 不是在數據庫中自動生成的,只有UserProfile的主鍵是自動生成的(作為關系的主體)。

UserProfileJogger或兩者插入數據庫的方式如下:

  • 如果要在沒有Jogger的情況下插入UserProfile ,只需將其添加到上下文中:

     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(); } 
  • 如果要在一個步驟中插入帶有JoggerUserProfile

     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 (它必須是現有UserProfileJogger ):

     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
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM