为什么ApplicationUser中的自定义对象属性为null?

时间:2015-04-03 04:04:44

标签: c# asp.net asp.net-mvc entity-framework asp.net-mvc-5

我创建了一个名为Person的自定义类来存储名称,地址等。此类/模型与其他模型交叉引用,包括ApplicationUser

public class ApplicationUser : IdentityUser
{
    public Person Person { get; set; }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

在我的一个控制器中,我使用以下代码来获取当前用户登录并获取它的Person对象,如下所示:

        var user = UserManager.FindById(User.Identity.GetUserId());
        var person = user.Person;

我的Person课程也在ApplicationDbContext

中定义
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("MyContext", throwIfV1Schema: false)
    {
    }

    public DbSet<Person> People { get; set; }
}

当我检查user时,我可以看到实体框架填充了对象,因为我看到了用户ID,电子邮件地址,密码哈希,一切!一切 除了 Person属性!但是,我可以在数据库中看到相应的行不是null,但具有Person的正确ID。

我是ASP.NET / MVC / Entity框架的新手,我已经读过它默认使用延迟加载。这是我遇到的情况吗?如果是这样,我如何告诉实体在Person属性上使用预先加载?如果没有,我做错了什么?

3 个答案:

答案 0 :(得分:5)

这可能是一个映射问题。实体框架映射太复杂了,我无法在这里解释,但我会指出问题可能在哪里。

确保ApplicationUser具有Person的外键属性,以实体框架可以理解它。实体框架是基于约定的,因此默认情况下它将在PersonId类中查找ApplicationUser属性。如果您不想使用默认名称,可以在Context OnModelCreating上使用流畅配置为其指定自定义名称。

我个人认为手动映射所有关系总是一个好主意。这是一个例子:

public void OnModelCreating(ModelBuilder modelBuilder)
{
    builder.Entity<ApplicationUser>().HasRequired(m => m.Person).HasForeignKey(d => d.Person) 
}

有关详细信息,请参阅此链接:https://msdn.microsoft.com/en-us/data/jj591620.aspx

答案 1 :(得分:1)

我会使Person类继承自IdentityUserApplicationUser。然后,我将在dbcontext类中具有以下内容:

DbSet<Person> People {get;set;}

然后你可以使用它:

MyDbContext db = new MyDbContext();    
string userid = User.Identity.GetUserId();
var user = db.People.Single(p=>p.Id == userid );

答案 2 :(得分:0)

在实体框架代码中,第一种方法是实体框架将第一个整数属性作为主键。所以在这里你在应用程序User类中添加Person类的引用。您可以尝试这样:

[ForeignKey的( “PERSONID”)]

public virtual Person Person {get; set;}

public int PersonId {get; set;}

这将使PersonId成为应用程序用户表中的外键。您也可以将其置为可空

public int? PERSONID {获得;设置;}

从那里你可以获得在应用程序用户表中插入的Person对象的Id,然后你就可以获得person对象的属性。

我希望这可以帮助你,因为这会映射两个表之间的关系。