.NET Identity UserManager.FindAsyc抛出“无效的列名'Discriminator'。”

时间:2013-11-15 19:14:56

标签: asp.net-mvc asp.net-identity

我创建了一个新的.NET Web应用程序项目,并为我选择的模板选择了单个用户帐户身份验证。默认情况下,这会将Identity数据库设置为App_Data目录中的本地数据库。这很好。但后来我需要AspNet表的成员资格在我真正的SQL Server数据库中,该数据库包含我的应用程序的其余部分。所以我将DefaultConnection字符串更改为指向我的本地SQL Server数据库,当我重新启动应用程序时,EF会自动在我的真实数据库中创建这些表。所以一切都很好。

然后,当我尝试登录并调用UserManager.FindAsync时,它给出了以下SqlException:“无效的列名'Discriminator'。”。完整的StackTrace在下面供参考。

我正在使用默认Web应用程序模板附带的相同ApplicationDbContext和ApplicationUser。

对于我做错了什么的任何想法?这是我第一次使用.NET Identity。除了更改连接字符串之外,是否有其他方法可以使它与现有SQL Server数据库一起使用?

感谢。

完整堆栈跟踪:

   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)\r\n   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)\r\n   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)\r\n   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)\r\n   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()\r\n   at System.Data.SqlClient.SqlDataReader.get_MetaData()\r\n   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)\r\n   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)\r\n   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)\r\n   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)\r\n   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)\r\n   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)\r\n   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)\r\n   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<>c__DisplayClassb.<Reader>b__8()\r\n   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TInterceptionContext,TResult](Func`1 operation, TInterceptionContext interceptionContext, Action`1 executing, Action`1 executed)\r\n   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)\r\n   at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)\r\n   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)\r\n   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)

3 个答案:

答案 0 :(得分:2)

两种不同的DbContexts? 错误消息可能是由DbContext创建的数据库引起的,该数据库具有IdentityUser类型的DbSet,或者更可能是某种与IdentityUser相关的实体。而UserManager似乎正在使用另一个Context(ApplicationDbContext?),其中包含一个继承自IdentityUser的类型的DbSet。当你的模型实体框架中有一个继承自另一个类型的类型时,将使用/期望一个名为discriminator的列,它将包含存储在特定行中的实体的类型名称。

答案 1 :(得分:1)

如果自托管WEB API创建了数据库,然后您尝试从ASP.NET MVC站点访问它,也会发生此错误。这两个项目都是VS 2013中的默认项目。

正如Olav Nybo所说,这可能与ASP.NET MVC尝试登录为继承自IdentityUser的ApplicationUser有关。 对我来说,快速解决方法是从ASP.NET MVC网站生成数据库。

答案 2 :(得分:1)

参加聚会的时间不多,但我在这里看到的是,在扩展IdentityUser时,AspNetUsers表需要使用新的自定义列来表示正在使用的属性,以及一个列用于IdentityUser的类型。

例如,如果您要创建一个新的ApplicationUser:IdentityUser,那么名为Discriminator的表中将有一个新列,它的值为ApplicationUser。这是您不使用Code First的情况,您需要手动应用数据库更改。