4

在阅读了这篇关于向 UserProfile 表添加自定义数据的好BLOG之后,我想将其更改为 UserProfile 表应该存储默认数据的方式 + 另一个存储所有附加信息的类。

使用 Internet 应用程序模板创建新项目后,我创建了两个类:

学生.cs

[Table("Student")]
public class Student
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public virtual int StudentId { get; set; }
    public virtual string Name { get; set; }
    public virtual string Surname { get; set; }
    public virtual int UserId { get; set; }
}

用户配置文件.cs

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

另外,我已经从 AccountModel.cs 中删除了 UserProfile 定义。我的数据库上下文类如下所示:

MvcLoginDb.cs

public class MvcLoginDb : DbContext
{
    public MvcLoginDb()
        : base("DefaultConnection")
    {
    }

    public DbSet<UserProfile> UserProfiles { get; set; }
    public DbSet<Student> Students { get; set; }
}

再次,我从 AccountModel.cs 中删除了 db 上下文定义。

在 Package-Manager-Console 里面我写过:

Enable-Migrations

我的 Configuration.cs 看起来像这样:

internal sealed class Configuration : DbMigrationsConfiguration<MvcLogin.Models.MvcLoginDb>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    }

    protected override void Seed(MvcLogin.Models.MvcLoginDb context)
    {
        WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

        if (!WebSecurity.UserExists("banana"))
            WebSecurity.CreateUserAndAccount(
                "banana",
                "password",
                new
                {
                   Student = new Student { Name = "Asdf", Surname = "Ggjk" }
                });

    }
}

这是将学生数据添加为创建新班级的想法,但这种方法不起作用,因为在运行Update-Database -Verbose后我收到错误: 从对象类型 MvcLogin.Models.Student 到已知托管的不存在映射提供者本机类型。

任何人都可以解释为什么我会收到这个错误,我应该使用不同的方法在不同的表中存储额外的数据吗?

4

2 回答 2

3

我在同样的问题上挣扎了很多。关键是让 UserProfile 类和您的 Student 类之间的关系正确。它必须是一对一的关系才能正常工作。

这是我的解决方案:

个人.cs

public class Person
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    /* and more fields here */

    public virtual UserProfile UserProfile { get; set; }
}

用户配置文件.cs

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

    public virtual Person Person { get; set; }
}

MyDbContext.cs

public class MyDbContext : DbContext
{
    public DbSet<Person> Person { get; set; }
    public DbSet<UserProfile> UserProfile { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
     modelBuilder.Entity<UserProfile>()
                    .HasRequired(u => u.Person)
                    .WithOptional(p => p.UserProfile)
                    .Map(m => m.MapKey("PersonId"));
    }
}

但是,我也很难使用 WebSecurity.CreateUserAndAccount 方法创建用户。所以我最终使用 Entity Framework 创建了我的 Person 对象,然后使用成员资格提供程序方法创建了用户帐户:

AccountRepository.cs

 public Person CreatePerson(string name, string username) {

     Person person = new Person { Name = name };
     _dbContext.Person.add(person);
     _dbContext.SaveChanges();

     var membership = (SimpleMembershipProvider)Membership.Provider;
     membership.CreateUserAndAccount(
         model.UserName, 
         createRandomPassword(), 
         new Dictionary<string, object>{ {"PersonId" , person.Id}}
     );

 }
于 2013-03-14T21:35:07.743 回答
0

HenningJ,我正在寻找同样问题的答案。不幸的是(我相信你知道)你这样做的问题是没有 SQL 事务。您的 SaveChanges() 或 CreateUserAndAccount() 可能会失败,从而使您的用户数据库处于无效状态。如果失败,您需要回滚。

我仍在寻找最终答案,但我会发布我最终使用的任何解决方案。希望避免编写自定义会员提供程序(再次!),但开始认为它会更快。

于 2013-07-19T20:41:04.987 回答