ApplicationUser模型的VS 2013控制器脚手架失败(不支持每种类型的多个对象集)

时间:2013-11-10 10:22:30

标签: scaffolding

在使用EF 6的VS 2013 RTM,MVC 5项目中,我尝试使用基于ApplicationUser的控制器(默认使用个人帐户身份验证)来构建控制器。 ApplicationUserIdentityUser都映射到Users表。 该向导打开上下文文件以进行编辑,并尝试为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的模型,则脚手架还会向上下文类添加一个额外的数据库集(如果我删除它并修复生成控制器中的引用,该应用程序就可以工作)。

9 个答案:

答案 0 :(得分: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; }

您现在拥有两个DbSet跟踪的同一实体,并且您收到该错误。解决方案?只是不要为DbSet添加自己的ApplicationUser。没有必要重命名或覆盖任何内容。

答案 1 :(得分:16)

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

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

最初,我认为这是一个预览问题,但在与最新的库一起持续进入RTM之后,我变得非常恼火,因为这个问题也一直存在于迁移中。

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

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

由此,我们(以及脚手架引擎和迁移引擎)应该只看到“用户”,而不是“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对象,导致实体迁移和脚手架发出这些错误。

希望这有帮助!

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

编辑: 如果您收到进一步的问题,请撤消重命名。我遇到了一些问题(更多脚手架和查询错误),在我回到ApplicationUser后,这些问题就消失了,上面的问题也解决了不再发生。只是一个抬头。

答案 2 :(得分:7)

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

  

不支持每种类型的多个对象集。对象集   &#39; ApplicationUsers&#39;和&#39;用户&#39;都可以包含类型的实例   &#39; DataLayerIdentity.Models.ApplicationUser&#39;

我怀疑错误是在我玩的时候创建的,并且在模型中搭建了架构:ApplicationUser在新控制器中。

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

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

否其他更改解决问题的方法。我希望这有助于某人。

答案 3 :(得分:7)

当您使用scaffolding生成控件时,vs会自动将1行插入到您的db上下文

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

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

答案 4 :(得分:5)

我花了一天多的时间来解决这个问题... :(((重命名类只是解决方法。正确的解决办法是从ApplicationContext(IdentityModels.cs)中删除这一行。我不知道它什么时候被插入我的代码。

System.Data.Entity.DbSet ApplicationUsers {get;组; }

用户在内部管理,此处应该有USER DEFINED TABLES。这意味着这个错误的行是第二次出现,这就是“多个对象集”错误消息的原因。

删除此行并编译后,我在自动生成的视图代码中收到了几条错误消息,因为它已经引用了错误的声明。您可以手动重新创建视图或修复代码,只需简单地重命名对ApplicationUser的错误引用以更正用户(在内部正确定义,而不是在IdentityModels.cs中)

在尝试查找解决方案期间,我也损坏了我的迁移,因此我不得不从头开始将数据结构迁移到DB。

现在我完全从这个问题中恢复过来,几乎ROOT问题很明显。不幸的是,根本问题可能是VS2013中的一个错误,它会产生错误的附加线。

但无论如何,继续微笑。与Java中的编程相比,面对这样的错误是没有的:)

答案 5 :(得分:1)

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

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

只需删除此属性即可解决问题。

答案 6 :(得分: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并删除此行AGAIN

    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. 按播放和交叉手指:)

答案 7 :(得分:0)

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

    protected ApplicationDbContext db { get; private set; }

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

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

然后创建索引,创建等方法,并通过右键单击和“添加视图...”创建视图。 使用列表,创建任何适当的模板来支持您的视图,并选择ApplicationUser作为模型。

重要说明:删除“数据上下文类”中的条目,否则您将再次收到类似错误。但是如果你把“数据上下文类”留空,那么视图的脚手架就可以了。

答案 8 :(得分:0)

我通过从上下文中删除DbSet然后将控制器中的引用从ApplicationUsers更改为Users来修复问题。它工作 - 但现在我认为脚手架用户没有意义。 要做很多事情必须保持在最高水平,它只是不能正常工作。现在我知道视图模型和存储库是我想要的方式。