19

在带有 EF 6 的 VS 2013 RTM、MVC 5 项目中,我尝试构建基于 ApplicationUser 的控制器(默认使用个人帐户身份验证)。两者ApplicationUserIdentityUser映射到用户表。该向导打开上下文文件进行编辑并尝试为 ApplicationUser (ApplicationUsers) 添加一个新的数据库集,然后失败并出现以下错误:

Unable to retrieve metadata for ApplicationUser. Multiple object sets per type are not supported. The object sets ApplicationUsers and Users can both contain instances of type ApplicationUser 该解决方案没有任何引用或实例ApplicationUsers

这是一个已知的问题?可以使用带有选项的命令行(来自 PMC)运行脚手架吗?注意:如果我指定一个引用 ApplicationUser 的模型,脚手架还会向上下文类添加一个额外的数据库集(如果我删除它并修复生成控制器中的引用,则应用程序可以工作)。

4

8 回答 8

32

哇。我真的很惊讶没有人真正找到它的根源,而只是推荐解决方法。

IdentityDbContext已经包含一个属性:

`public virtual IDbSet<TUser> Users { get; set; }

当您IdentityDbContext创建自己的应用程序特定上下文的子类时,您必须指定满足TUser泛型的类。默认值为:

public ApplicationDbContext : IdentityDbContext<ApplicationUser>

这意味着您在功能上已经通过以下形式的继承拥有了一个属性:

public IDbSet<ApplicationUser> Users { get; set; }

如果您随后将另一个属性添加到特定于应用程序的上下文中,例如:

public DbSet<ApplicationUser> ApplicationUsers { get; set; }

您现在有两个DbSets 跟踪的相同实体,您会收到该错误。解决方案?简单地不要添加你自己的DbSetfor ApplicationUser。无需重命名或覆盖任何内容。

于 2014-08-26T14:41:23.533 回答
17

短版:将您的 ApplicationUser 类重命名为 User。

我已经遇到这个问题大约一个月了,完全没有运气......直到现在!

最初,我认为这是一个预览问题,但在坚持使用 RTM 和最新的库之后,我变得非常恼火,因为这个问题也持续存在于 Migrations 中。

但是,根据错误消息,IdentityDbContext 似乎正在创建两个 DbSet:ApplicationUsers 和 Users。在查看源代码时,我们只需要用户:

public class IdentityDbContext<TUser> : DbContext where TUser : Microsoft.AspNet.Identity.EntityFramework.IdentityUser
{
    ...
    public virtual IDbSet<TUser> Users { get; set; }
    ...
}

由此,我们(以及脚手架引擎和迁移引擎)应该只看到“Users”,而不是“ApplicationUsers”。

要纠正这种情况,您需要调整您的应用程序类来解决这个相当奇怪的错误。只需将 ApplicationUser 类重命名为 User:

using Microsoft.AspNet.Identity.EntityFramework 
...
public class ApplicationUser : IdentityUser
{
    Your Stuff
}

至:

using Microsoft.AspNet.Identity.EntityFramework 
...
public class User: IdentityUser
{
    Your Stuff
}

再次尝试脚手架。如果您收到另一个类似找不到类的错误,请保存您的项目,关闭 VS2013,重新打开 VS2013,加载项目,重新构建项目,最后尝试脚手架。IdentityDBContext 不应再创建一个虚拟的“ApplicationUsers”DBSet 对象,从而导致实体迁移和脚手架发出这些错误。

希望这可以帮助!

PS 完成的任何映射都不应该影响这个问题,所以如果你愿意的话,你应该仍然可以映射到同一个表。

编辑: 如果您收到更多问题,请撤消重命名。我遇到了一些问题(更多的脚手架和查询错误),在我回到 之后ApplicationUser,这些问题消失了,上面的问题也没有再次出现。只是一个抬头。

于 2013-12-07T00:30:55.323 回答
7

当您使用脚手架生成控件时,vs 会自动将 1 行插入到您的数据库上下文中

public System.Data.Entity.DbSet<...API.Models.ApplicationUser> ApplicationUsers { get; set; }

只需删除该行,并在您的控制器中。更改 db.ApplicationUsersdb.Users

于 2015-01-24T06:52:27.450 回答
7

阅读上述问题和解决方案。我的错误文本是:

不支持每种类型的多个对象集。对象集“ApplicationUsers”和“Users”都可以包含“DataLayerIdentity.Models.ApplicationUser”类型的实例

我怀疑这个错误是在我玩耍并搭建模型时产生的:ApplicationUser 在一个新的控制器中。

通过从以下内容中删除以下内容来解决它:ApplicationDbContext.cs

    public System.Data.Entity.DbSet<DataLayerIdentity.Models.ApplicationUser> ApplicationUsers
    {
        get;
        set;
    }

没有为解决问题而进行的其他更改。我希望这可以帮助别人。

于 2014-08-12T16:03:32.810 回答
1

这是最简单的解决方案。当您添加/搭建基于 ApplicationUser 作为模型的视图(列表)时,VS2013 将以下内容添加到 IdentityModels.vb 或 .cs 文件中:

公共属性 ApplicationUsers 作为 System.Data.Entity.DbSet(Of ApplicationUser)

只需删除此属性,问题就会消失。

于 2014-10-11T01:27:44.227 回答
1

如果您尝试创建 ApplicationUsersController,请按照以下步骤操作。

  1. 从 IdentityModels.cs 中删除这一行

    public System.Data.Entity.DbSet<Project.Models.ApplicationUser> ApplicationUsers { get; set; }
    
  2. 构建项目

    control + shift + b
    
  3. 生成控制器

    Right click on the 'Controllers' folder.
    Add > Controller
    MVC Controller with views, using Entity Framework
    Model Class: ApplicationUser
    Add
    
  4. 返回 IdentityModels.cs 并再次删除此行

    public System.Data.Entity.DbSet<Project.Models.ApplicationUser> ApplicationUsers { get; set; }
    
  5. 构建项目

    control + shift + b
    
  6. 将数据库调用从 ApplicationUsers 更改为 ApplicationUsersController.cs 中的用户

    control + f to bring up 'Find and Replace'
    Click 'Replace in files'
    Find what: db.ApplicationUsers
    Replace with: db.Users
    Replace All
    
  7. 按播放和交叉手指:)

于 2015-10-01T22:45:37.480 回答
0

我通过从上下文中删除 DbSet 然后将控制器中的引用从 ApplicationUsers 更改为 Users 来解决问题。它奏效了——但现在我认为给用户搭建脚手架毫无意义。很多事情都必须保持在顶层,它就是不能正常工作。现在我知道视图模型和存储库是我想要的方式。

于 2014-04-09T20:19:48.823 回答
0

您还可以做什么:创建一个空控制器,并自己添加 DataContext 的代码

    protected ApplicationDbContext db { get; private set; }

    public HomeController() : this(new ApplicationDbContext())
    {
    }

    public HomeController(ApplicationDbContext db)
    {
        this.db = db;
    }

然后创建您的方法,如索引、创建等,并通过右键单击和“添加视图...”为每个视图创建视图。用列表搭建您的视图,创建任何合适的模板,然后选择 ApplicationUser 作为模型。

重要提示:删除“数据上下文类”中的条目,否则您将再次收到类似错误。但是,如果您将“数据上下文类”留空,则视图的脚手架将正常工作。

于 2014-01-31T10:15:22.157 回答