ApplicationUser不是当前上下文的模型的一部分

时间:2015-04-29 10:09:03

标签: c# entity-framework asp.net-mvc-4 asp.net-identity dbcontext

我有一个ASP MVC项目,我是从同事那里获得的,它有2个上下文。一个来自登录所需的模板,另一个是自制的。所以我想把两者合并,但我总是得到这个错误:

D:\Word>A.pl
D0033   D0033   15      E08.07No                     Committee

该模型是数据库优先。我先创建了我的SQL表,然后创建了一个ADO.NET实体数据模型,它给出了我的这个connectionString:

ApplicationUser is not part of the model for the current context

在此数据库中,添加了所需的ASP.NET表,并且还添加了数据模型。我通过Migration添加了ASP.NET表。

这是我的DbContext类:

<add name="DairyCowBarnEntities" connectionString="metadata=res://*/Models.DairyCowBarnModel.csdl|res://*/Models.DairyCowBarnModel.ssdl|res://*/Models.DairyCowBarnModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=server;initial catalog=DairyCowBarn;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

我已经读过ApplicationUser需要一个正常的connectionString,如下所示:

public partial class DairyCowBarnEntities : IdentityDbContext<ApplicationUser>
{
    public DairyCowBarnEntities()
        : base("name=DairyCowBarnEntities")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public static DairyCowBarnEntities Create()
    {
        return new DairyCowBarnEntities();
    }

    public virtual DbSet<C__MigrationHistory> C__MigrationHistory { get; set; }
    public virtual DbSet<C__RefactorLog> C__RefactorLog { get; set; }
    public virtual DbSet<AspNetRole> AspNetRoles { get; set; }
    public virtual DbSet<AspNetUserClaim> AspNetUserClaims { get; set; }
    public virtual DbSet<AspNetUserLogin> AspNetUserLogins { get; set; }
    public virtual DbSet<AspNetUser> AspNetUsers { get; set; }

    public virtual DbSet<jntConcentrateMixture> jntConcentrateMixtures { get; set; }
    public virtual DbSet<jntConsistingParcel> jntConsistingParcels { get; set; }

}

但是我收到了这个错误:

<add name="DairyCowBarnEntities" connectionString="Data Source=server;Initial Catalog=DairyCowBarn;Integrated Security=True" providerName="System.Data.SqlClient" />

我不知道如何将两者结合起来。我没有想法。任何帮助都非常感谢,非常需要。希望我能清楚地解释清楚。否则只要询问是否需要更多信息。

1 个答案:

答案 0 :(得分:1)

当您对数据库进行逆向工程时,它将引入您不需要的AspNet表。您需要的唯一身份验证模型是

public class ApplicationUser : IdentityUser
{
    public DateTimeOffset CreatedOn { 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;
    }
}

我已经在我的AspNetUsers表中添加了一个CreatedOn列,这就是为什么它在上面的模型中。下一步是确保您的DbContext派生自IdentityDbContext<ApplicationUser>。此基类将处理到AspNet表的映射。所以你的DbContext应该是这样的:

public partial class DairyCowBarnEntities : IdentityDbContext<ApplicationUser>
{
    public DairyCowBarnEntities()
        : base("name=DairyCowBarnEntities")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public static DairyCowBarnEntities Create()
    {
        return new DairyCowBarnEntities();
    }

    public virtual DbSet<jntConcentrateMixture> jntConcentrateMixtures { get; set; }
    public virtual DbSet<jntConsistingParcel> jntConsistingParcels { get; set; }

}

这样做,删除所有关于AspNet的模型以及代码中对这些模型的所有引用。添加ApplicationUser模型但不为其创建DbSet并将其传递到派生类IdentityDbContext<ApplicationUser>。 IdentityDbContext将处理有关身份验证和授权的所有内容,因此您可以正常使用UserManager和Identity。

注意,我的CreatedOn是使用默认(sysdatetimeoffset())生成的数据库,但从未起作用。我必须在代码中显式设置CreatedOn,或者将其作为DateTimeOffset.MinValue填充到数据库。

已更新以回复评论:

您的db上下文派生自的IdentityDbContext<ApplicationUser>处理为您映射的句柄。它提供了一层抽象,因此您不必担心它。如果你需要查询那些超出UserManager将为你做什么的表,即;获取所有用户未确认的电子邮件地址,您始终可以编写自己的select语句并将其传递到dbContext,如dbContext.Database.SqlQuery<T>(sqlQuery, false); T,在这种情况下,您将创建一个应具有相同属性名称和类型的模型作为您要查询的列名称。 以下示例

public Users
{
    public string UserName { get; set; }
    public bool EmailConfirmed { get; set; }
}

var sqlQuery = "SELECT Users.UserName, Users.EmailConfirmed FROM AspNetUsers WHERE Users.EmailConfirmed = {0}"
var unconfirmedUsers = dbContext.Database.SqlQuery<Users>(sqlQuery, false).ToList();

使用{0}并将值作为参数传入将自动清除该值,因此不会使用sql注入脚本。