C# EntityType'';IdentityUserRole';没有键定义错误
首先使用实体框架代码 尝试将IdentityRole id用作自定义类的外键 该关系是正确的,但当我尝试向自定义表添加数据时,会出现此错误 EntityType“IdentityUserRole”未定义键。定义 这个实体类型。IdentityUserRoles:EntityType:EntitySet “IdentityUserRole”基于没有 已定义关键点 代码: 自定义表格/类别C# EntityType'';IdentityUserRole';没有键定义错误,c#,entity-framework,asp.net-mvc-5,ef-code-first,C#,Entity Framework,Asp.net Mvc 5,Ef Code First,首先使用实体框架代码 尝试将IdentityRole id用作自定义类的外键 该关系是正确的,但当我尝试向自定义表添加数据时,会出现此错误 EntityType“IdentityUserRole”未定义键。定义 这个实体类型。IdentityUserRoles:EntityType:EntitySet “IdentityUserRole”基于没有 已定义关键点 代码: 自定义表格/类别 public class UserRoleAccess { [Key] public long
public class UserRoleAccess
{
[Key]
public long UserRoleAccessId { get; set; }
public string UserRoleId { get; set; }
public virtual ApplicationRole ApplicationRole { get; set; }
public bool IsActive { get; set; }
public string Name { get; set; }
public int UserRoleAccessType { get; set; }
}
识别码:
public class ApplicationRole : IdentityRole
{
public virtual ICollection<UserRoleAccess> UserRoleAccess { get; set; }
}
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<IdentityUser>().ToTable("Users").Property(p => p.Id).HasColumnName("UserId");
modelBuilder.Entity<ApplicationUser>().ToTable("Users").Property(p => p.Id).HasColumnName("UserId");
modelBuilder.Entity<IdentityUserRole>().ToTable("UserRoles");
modelBuilder.Entity<IdentityUserLogin>().ToTable("UserLogins");
modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaims");
modelBuilder.Entity<IdentityRole>().ToTable("Roles");
modelBuilder.Entity<ApplicationRole>().ToTable("Roles");
modelBuilder.Entity<UserRoleAccess>().ToTable("UserRoleAccess");
modelBuilder.Entity<ApplicationUser>().HasRequired(p => p.Person)
.WithMany(b => b.Users);
modelBuilder.Entity<ApplicationUser>().HasRequired(p => p.Person)
.WithMany(b => b.Users)
.HasForeignKey(p => p.PersonId);
modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
modelBuilder.Entity<ApplicationRole>().HasKey<string>(r => r.Id);
modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });
}
添加数据时运行以下代码:
public static void CreateUserRoleAccess(string name, int type, string id)
{
using (var context = new UserRoleAccessContext())
{
var userRoleAccess = new UserRoleAccess();
userRoleAccess.ApplicationRole = new ApplicationRole { Id = id };
userRoleAccess.UserRoleId = id;
userRoleAccess.IsActive = true;
userRoleAccess.UserRoleAccessType = type;
userRoleAccess.Name = name;
context.UserRoleAccess.Add(userRoleAccess);
context.SaveChanges();
}
}
我错过了什么
编辑:
识别码等级:
因此,您正在使用
MVC5
和ASP.NET Identity 2.0
。我猜您的项目中有Microsoft.AspNet.Identity.EntityFramework的Nuget包,并且已经在您的数据库中创建了正确的表
您的问题可能是因为您正在重新定义标准标识表的映射。您真的需要显式映射表名和键吗?我会尽量保留原始映射,只为自定义实体和字段添加显式映射。
我认为您不需要ToTable映射,因为基本实体在其代码中的某个地方有一个映射,并且您的实体扩展了它们
有几个问题:
的含义是什么?它是用户id还是角色id?如果要包含UserRole id,则它是一个组合键,而不是单个值,因此字符串属性不太可能这样做。也许你应该给它改名UserRoleAccess.UserRoleId
- 在方法
中,您想做什么:为已经存在且已经相关的角色和用户添加新的CreateUserRoleAccess
(即,UserRoleAccess
关系已经存在)?或者为已经存在但不相关的用户和角色添加新的UserRole
和UserRole
?我假设此时您不想创建角色或用户,他们已经存在,我错了吗UserRoleAccess
- 无论如何,在CreateUserRoleAccess方法中,在这一行:
除非此时正在创建新角色,否则您应该执行userRoleAccess.ApplicationRole = new ApplicationRole { Id = id };
或其他Linq查询,并从上下文中获取现有角色。也许仅仅改变这一点就可以让代码正常工作:查找
//userRoleAccess.ApplicationRole = new ApplicationRole { Id = id }; userRoleAccess.ApplicationRole = context.Roles.Find(id) as ApplicationRole;
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public virtual IDbSet<UserRoleAccess> UserRoleAccesses { get; set; }
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
请注意,我首先创建了一个具有不同上下文范围的新角色,以确保在获得感兴趣的代码时该角色存在。我以后从上下文中获取该角色
希望这有帮助。如果你愿意,我可以给你发送整个解决方案代码
编辑-用户角色访问表:
有用链接:
-我使用此信息创建了简单的MVC解决方案
我们在ObjectType之前不使用new关键字,是吗?public新字符串Id{get;set;}@Waleed resharper添加了一些东西。你的评论有什么帮助?在属性前面有或没有new关键字,它仍然不起作用。您可以发布IdentityRole类吗?在模型中有到IdentityRole键的映射builder@matthijsb它是内置的Ef类:错误消息表示错误与实体IdentityUserRole有关,而不是与IdentityRole有关。您的映射没有定义此实体和其他实体之间的关系,因此EF可能正在隐式创建此实体的关系。是否在“UserRoles”表中的DB中生成PK?你能展示实体识别码你的角色吗?投票支持努力!非常感谢。虽然我不确定你是否完全明白我想做什么。能否显示UserRoleAccess表的外观图像?在我看来,您似乎拥有来自AspNetUsers表和AspnetRole表的forein键。我只希望从aspNetRoles表中获得一个key属性。在CreateUserRoleAccess方法中,id属性为我们提供一个已经存在的角色的id。我会尝试按照你的建议找到身份证。不客气!我在答案中添加了UserRoleAccess表。AspNetRoles表中有一个外键,而不是AspNetUsers表中的外键。因此,您希望使用属性UserRoleId作为外键字段,使用ApplicationRole作为导航属性?您可以使用ForeignKey属性实现这一点,如下所示:
[ForeignKey(“UserRoleId”)]公共虚拟应用程序角色ApplicationRole{get;set;}
。您可以将属性放在ApplicationRole属性或UserRoleId属性中,参数必须是其他属性名称。如果这样做,ApplicationRole_Id字段将不再自动生成(因为字段UserRoleId将在外键中使用)。为了清晰起见,我建议将UserRoleId的名称更改为ApplicationRoleId。如果您喜欢流畅的映射而不是注释,可以使用OnModelCreating方法中的以下代码来实现:modelBuilder.Entity().HasRequired(ura=>ura.ApplicationRole).WithMany().HasForeignKey(ura=>ura.UserRoleId)代码>
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public virtual IDbSet<UserRoleAccess> UserRoleAccesses { get; set; }
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
public void CreateUserRoleAccess(string name, int type, string id)
{
//Insert role (run only once)
using (var context = new ApplicationDbContext())
{
var role = new ApplicationRole { Id = id, Name = "Role1" };
var user = context.Users.FirstOrDefault<ApplicationUser>();
//user.Roles.Add(role);
role.Users.Add(new IdentityUserRole { RoleId = role.Id, UserId = user.Id });
context.Roles.Add(role);
context.SaveChanges();
}
using (var context = new ApplicationDbContext())
{
var userRoleAccess = new UserRoleAccess();
//userRoleAccess.ApplicationRole = new ApplicationRole { Id = id };
userRoleAccess.ApplicationRole = context.Roles.Find(id) as ApplicationRole;
//Is this a userId or a roleId? Does not seem OK to assign id param here
userRoleAccess.UserRoleId = id;
userRoleAccess.IsActive = true;
userRoleAccess.UserRoleAccessType = type;
userRoleAccess.Name = name;
context.UserRoleAccesses.Add(userRoleAccess);
context.SaveChanges();
}
}
CreateTable(
"dbo.UserRoleAccesses",
c => new
{
UserRoleAccessId = c.Long(nullable: false, identity: true),
UserRoleId = c.String(),
IsActive = c.Boolean(nullable: false),
Name = c.String(),
UserRoleAccessType = c.Int(nullable: false),
ApplicationRole_Id = c.String(maxLength: 128),
})
.PrimaryKey(t => t.UserRoleAccessId)
.ForeignKey("dbo.AspNetRoles", t => t.ApplicationRole_Id)
.Index(t => t.ApplicationRole_Id);