在asp.net身份中配置一对一关系

时间:2015-10-08 13:06:32

标签: entity-framework ef-code-first asp.net-identity one-to-one

这是我的ApplicationUser类。我只添加了一个新属性----

  public class UserProfileInfo
  { 
   // [Key, ForeignKey("ApplicationUser")]
    [Key]
    public int Id { get; set; }
    public int ImageSize { get; set; }
    public string FileName { get; set; }
    public byte[] ImageData { get; set; }

   [ForeignKey("Id")]
    public virtual ApplicationUser ApplicationUser { get; set; }
}

这是我的userProfileInfo类,我想在完成注册后保存每个用户的个人资料图片----

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }

    public DbSet<UserProfileInfo> UserProfileInfo { get; set; }

这是我的DbContext类-----

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       // base.OnModelCreating(modelBuilder);

        //// Configure Id as PK for UserProfileInfo class
        modelBuilder.Entity<UserProfileInfo>()
            .HasKey(e => e.Id);

        // Configure Id as FK for UserProfileInfo
        modelBuilder.Entity<ApplicationUser>()
            .HasOptional(s => s.UserProfileInfo)
            .WithRequired(ad => ad.ApplicationUser);
    }

现在,问题是我无法配置ApplicationUser类和UserProfileInfo类之间的一对一关系。我已尝试过各种方法来执行此操作并遵循一些堆栈溢出问题,但是在我完成注册表单后,它说错误------

无法确定类型&#39; CodeFirstContext.ApplicationUser&#39;之间关联的主要结尾。和&#39; CodeFirstContext.UserProfileInfo&#39;。必须使用关系流畅API或数据注释显式配置此关联的主要结尾。

我也试图在流畅的api -----

的帮助下建立关系
  Telefon: <input type="checkbox" id="telefon" name="telefon" value="true" class="knapp">

这样我也失败了。请建议我如何配置它。

1 个答案:

答案 0 :(得分:1)

你快到了。 首先,您可以删除属性上的所有注释(Key,foreignkey),因为按照惯例,使您的名称为Id的列成为主键(并且您的关系再次与此相关)。

其次,您只需要从一个实体流畅地映射您的关系,例如从Applicationuser到UserProfileInfo,如下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ApplicationUser>()
            .HasOptional(c => c.UserProfileInfo)
            .WithRequired(d => d.ApplicationUser);
        base.OnModelCreating(modelBuilder);
    }

注意:如果您的个人资料关系是可选的,则使用,否则使用HasRequired。 如果您现在想要为用户添加配置文件设置,您可以:

var user = UserManager.FindById(User.Identity.GetUserId());
var up = new UserProfileInfo {ImageSize = 12};
user.UserProfileInfo = up;
UserManager.Update(user);

有关ef流畅映射的更多信息,请访问:https://msdn.microsoft.com/en-us/data/hh134698.aspx

修改 要将UserProfileInfo分配给ApplicationUser,您可以:

1

// get user via UserManager
var user = UserManager.FindById(User.Identity.GetUserId());
// create new UserProfileInfo
var up = new UserProfileInfo {ImageSize = 12};
// assign UserProfileInfo to user, ef will figure out that this info goes into the corresponding UserProfileInfo table
user.UserProfileInfo = up;
// update via UserManager
UserManager.Update(user);

或2.

// logged in user id
var userId = User.Identity.GetUserId();
using (var db = new ApplicationDbContext())
{
     // get user from context
     var user = db.Users.First(c => c.Id == userId);
     // new UserProfileInfo
     var up = new UserProfileInfo {ImageSize = 12};'
     // assign UserProfileInfo to user
     user.UserProfileInfo = up;
     // save changes
     db.SaveChanges();
 }

最后,如果您想更新userprofileinfo而不是始终创建新的。你可以这样做:

// get existing or create new UserProfileInfo
var up = user.UserProfileInfo ?? new UserProfileInfo();
// update with new values 
up.ImageSize = 17;

请注意,您不需要关心外键ApplicationUser_Id,当您将UserProfileInfo分配给ApplicationUser时,EF会自行解决这个问题。

并且:如果您绝对想要在UserProfileInfo中公开ApplicationUser的外键。您可以在类UserProfileInfo中添加名为ApplicationUserId的属性。按惯例,Ef理解这一点。如果您需要为此外键使用其他名称,则可以使用.HasForeignKey(fk =&gt; fk.YourForeignKeyPropertyHere)扩展您的流畅映射