在使用EF 6的VS 2013 RTM,MVC 5项目中,我尝试使用基于ApplicationUser的控制器(默认使用个人帐户身份验证)来构建控制器。 ApplicationUser
和IdentityUser
都映射到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的模型,则脚手架还会向上下文类添加一个额外的数据库集(如果我删除它并修复生成控制器中的引用,该应用程序就可以工作)。
答案 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.ApplicationUsers
至db.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,请按照以下步骤操作。
从IdentityModels.cs
中删除此行public System.Data.Entity.DbSet<Project.Models.ApplicationUser> ApplicationUsers { get; set; }
构建项目
control + shift + b
生成控制器
Right click on the 'Controllers' folder.
Add > Controller
MVC Controller with views, using Entity Framework
Model Class: ApplicationUser
Add
返回IdentityModels.cs并删除此行AGAIN
public System.Data.Entity.DbSet<Project.Models.ApplicationUser> ApplicationUsers { get; set; }
构建项目
control + shift + b
将数据库调用从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 :(得分: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来修复问题。它工作 - 但现在我认为脚手架用户没有意义。 要做很多事情必须保持在最高水平,它只是不能正常工作。现在我知道视图模型和存储库是我想要的方式。