【发布时间】:2015-03-26 16:44:43
【问题描述】:
我在一个单独的库(例如 Common.Feedback.Data)中有一个数据库优先的 EDMX 模型,其中包括 AspNetUser 表及其相关的身份框架表(从另一个现有的、正在工作的数据库/应用程序中提取)。
我已更新ApplicationDbContext 连接字符串以指向新模型和新数据库连接:
using System.Data.Entity;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
namespace Feedback.MvcApplication.Models
{
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser
{
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;
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("FeedbackEntities", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
}
web.config 中的连接字符串包含程序集的完整路径,并且该引用很好:
<add name="FeedbackEntities"
connectionString="metadata=res://Common.Feedback.Data/FeedbackModel.csdl|res://Common.Feedback.Data/FeedbackModel.ssdl|res://Common.Feedback.Data/FeedbackModel.msl;provider=System.Data.SqlClient;provider connection string="data source=mydatabase.database.windows.net;initial catalog=Feedback;persist security info=True;user id=LeaveFeedbackuser@mydatabase;password=mypassword;MultipleActiveResultSets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
在运行时,任何对登录的访问都会导致以下错误:
“实体类型 ApplicationUser 不是当前上下文模型的一部分”
我尝试过的所有与该错误相关的链接通常都涉及更新迁移的方式。
我无法启用迁移,因为它是 EDMX 首次设置,但我假设 ApplicationUser 对象和 aspnetusers 表在幕后“某处”之间存在绑定。
这里有没有人清楚地了解ApplicationUser 类在运行时如何映射到aspnetusers 表/从aspnetusers 表映射并解释如何让我的代码与数据库一起使用?
重现步骤
- 使用 VS 2013 创建新的 MVC Web 应用程序
- 将所有 NuGet 包更新到最新版本
- 使用 Identity Framework 表获取现有 SQL 数据库并将其复制到新表中(删除所有不相关的表)。
- 为项目添加新表
- 创建一个类库来保存数据模型(例如
Common.Feedback.Data) - 根据之前创建的数据库,将 Edmx 数据模型添加到库中
- 更改连接字符串以完全限定程序集(不是
res://*/) - 更改
IdentityModel.cs中的连接字符串名称以匹配配置中的连接字符串名称。 - 将连接字符串从库的
app.config复制到Web 项目的web.config - 尝试登录,您将遇到上述错误
更新:
根据一篇杂散的帖子,我更改了连接字符串以匹配 Identity Framework 配置为默认使用的普通 SQL 连接(并使用 Sql 客户端):
<add name="FeedbackSql"
connectionString="data source=mydatabase.database.windows.net;initial catalog=Feedback;persist security info=True;user id=LeaveFeedbackuser@mydatabase;password=mypassword;MultipleActiveResultSets=True;App=EntityFramework"
providerName="System.Data.SqlClient" />
并更改为设置以使用此新连接:
public ApplicationDbContext()
: base("FeedbackSql", throwIfV1Schema: false)
{
}
奇怪的是错误变为:
GZip 标头中的幻数不正确。确保您传入的是 GZip 流。
我认为对 SqlClient 提供程序的初始更改是正确的,因此这个新错误可能与通过该连接使用 Azure 数据库有关。我愿意接受有关下一步尝试的建议。
根据@rism 和this link 的建议更新了web.config(但GZip 错误仍然存在):
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
<parameters>
<!--<parameter value="mssqllocaldb" />-->
<parameter value="data source=mydatabase.database.windows.net;initial catalog=Feedback;persist security info=True;user id=myuserid;password=mypassword;MultipleActiveResultSets=True;App=EntityFramework" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
再次根据@rism 的提示,我也尝试了这个版本(但 GZip 错误仍然存在):
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
<parameters>
<parameter value="v12.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
新更新:
我使用标准 user-security 选项创建了一个全新的 Web 应用程序。我还在 Azure 中创建了一个空数据库。
我什么也没做,只是将默认连接字符串更改为:
<connectionStrings>
<add name="DefaultConnection"
connectionString="data source=mydatabase.database.windows.net;initial catalog=Feedback;persist security info=True;user id=LeaveFeedbackuser;password=mypassword;MultipleActiveResultSets=True;App=EntityFramework"
providerName="System.Data.SqlClient" />
</connectionStrings>
和这个的默认连接工厂:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
<parameters>
<parameter value="v12.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
在尝试登录时,我收到以下错误:
GZip 标头中的幻数不正确。确保你是 传入 GZip 流。描述:未处理的异常 在执行当前 Web 请求期间发生。请 查看堆栈跟踪以获取有关错误和位置的更多信息 它起源于代码。
异常详细信息:System.IO.InvalidDataException:幻数 GZip 标头中的不正确。确保您传递的是 GZip 流。
来源错误:
第 153 行:{ 第 154 行:var user = new ApplicationUser { 用户名 = model.Email,Email = model.Email };线 155: var 结果 = 等待 UserManager.CreateAsync(用户, 型号.密码);第 156 行:if (result.Succeeded) 行 157:{
【问题讨论】:
-
如果您采用 DB-first 解决方案的路线,则没有理由坚持使用
ApplicationDbContext。您可以删除所有垃圾,拥有自己的 DbContext 并省去自己的头疼 -
您只展示了 ApplicationDbContext() 的构造函数,您可以展示整个类。另外,您使用的是哪个版本的身份?版本 1.0 与版本 2 完全不同。通过 EntityTypeConfiguration 的子类在类和表之间进行映射,您可以在其中设置模型的各个方面,例如映射参照完整性、基数等。如果您在 TspIdentityMap 中使用 Fluent Api:EntityTypeConfiguration
你会做出这样的声明。ToTable("AspNetUsers");即您将代码类实体 TspIdentity 映射到 db 表。 -
我想看到你的整个 ApplicationDbContext 的原因是,我读到的消息就像你的上下文中没有 DbSet
一样,但我通常会产生编译器错误......但是你已经混合和匹配了位,所以让我们看看都一样。还要检查您在所有项目中是否使用相同版本的 Identity。 -
@rism:我应该说,一切都是“开箱即用”的 Visual Studio 2013 脚手架 + MVC5 Razor 以及最新版本的“一切”。在我解决此问题之前,这目前只是一个简单的项目。
-
在默认项目的 web.config 中
标签: c# asp.net-mvc entity-framework-6 asp.net-identity ef-database-first