目前,我正在使用Mysql数据库在dotnet核心中使用Rest api。目前,我有两个带有用户和角色的表。对于我的项目,我需要获得用户和角色。在我的代码中,我指定了此样本中所述的关系
public DbSet<User> Users { get; set; }
private void InitEntityRole(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Role>(entity =>
{
entity.Property(e => e.Id).ValueGeneratedOnAdd().HasColumnName("Id");
entity.Property(e => e.Name).HasColumnName("naam");
});
}
private void InitEntityUser(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>(entity =>
{
entity.Property(e => e.Id).ValueGeneratedOnAdd().HasColumnName("Id");
entity.Property(e => e.Username).HasColumnName("gebruikersnaam");
entity.Property(e => e.PasswordHash).HasColumnName("wachtwoord");
entity.Property(e => e.PasswordSalt).HasColumnName("salt");
entity.HasOne(u => u.Person)
.WithOne(p => p.User)
.HasForeignKey<Person>(p => p.Id)
.HasConstraintName("fk_persoon");
entity.HasOne(u => u.Role)
.WithMany(r => r.Users)
.HasForeignKey(r => r.Id)
.HasConstraintName("fk_gebruikerrol");
});
}
在我的代码中,我有一个测试功能来检索所有这样的用户
public List<User> GetAll()
{
var users = _dbContext.Users.Include(u => u.Role).ToList();
users.ForEach(u => u.Password = null);
return users;
}
我的模特:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace DamstraChallengeBackend.Models
{
[Table("rol")]
public class Role
{
public int Id { get; set; }
public string Name { get; set; }
[JsonIgnore]
public ICollection<User> Users { get; set; }
}
}
和:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace DamstraChallengeBackend.Models
{
[Table("gebruiker")]
public class User
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Username { get; set; }
[NotMapped]
public string Password { get; set; }
[JsonIgnore]
public byte[] PasswordHash { get; set; }
[JsonIgnore]
public byte[] PasswordSalt { get; set; }
public Person Person { get; set; }
public Role Role { get; set; }
[NotMapped]
[JsonIgnore]
public string Token { get; set; }
}
}
我的表配置为
用户:
CREATE TABLE `gebruiker` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`gebruikersnaam` varchar(255) NOT NULL,
`wachtwoord` blob NOT NULL,
`salt` blob NOT NULL,
`p_id` int(11) NOT NULL,
`r_id` int(11) NOT NULL,
PRIMARY KEY (`Id`),
KEY `fk_persoon` (`p_id`),
KEY `fk_gebruikerrol` (`r_id`),
CONSTRAINT `fk_gebruikerrol` FOREIGN KEY (`r_id`) REFERENCES `rol` (`Id`),
CONSTRAINT `fk_persoon` FOREIGN KEY (`p_id`) REFERENCES `persoon` (`Id`)
)
ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_0900_ai_ci
角色:
CREATE TABLE `rol` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`naam` varchar(255) NOT NULL,
PRIMARY KEY (`Id`)
)
ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_0900_ai_ci
执行此代码时,我得到的只是一个空数组。我认为我在配置方面出错了,但似乎找不到。请任何人能帮助我。
我尝试过的事情是:忽略包含,然后得到一个数组,其中包含没有角色的用户。但是,一旦我添加了include语句,一切都不会显示。
我感到奇怪的是,当我有一个用户与一个组一起使用时,它可以工作。一旦添加更多,我得到的就是一个空数组。
对于英语中的错误我深表歉意,但我希望它足够清楚。
答案 0 :(得分:1)
编辑:在github上添加了具有in-memory-db-context的有效示例解决方案。
关系是错误的,这可能导致实体框架以这种方式运行。这是实体类型User
与实体类型Role
之间的多对多关系。一个用户具有0..1
至n
个角色,1
个角色已分配给0..n
个用户。
所以您需要做的是以下
1:添加同时包含外键和唯一标识符的映射实体类型UserRole
public class UserRole
{
public int Id { get; set; }
public int UserId { get; set; }
public User User { get; set; }
public int RoleId { get; set; }
public Role Role { get; set; }
}
2:调整实体类型的用户
public class User
{
// more code probably here
public virtual ICollection<UserRole> UserRoles { get; set; } // virtual keyword necessary for lazy loading, can be left out if not wanted
}
3:调整实体类型角色
public class Role
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<UserRole> UserRoles { get; set; } // virtual keyword necessary for lazy loading, can be left out if not wanted
}
4:在OnModelCreating(ModelBuilder builder)
内调整DbContext
方法,并删除旧的关系映射并添加新的映射。
protected override void OnModelCreating(ModelBuilder builder)
{
// existing code here
modelBuilder.Entity<UserRole>()
.HasOne(ur => ur.User)
.WithMany(u => u.UserRoles)
.HasForeignKey(ur => ur.RoleId);
modelBuilder.Entity<UserRole>()
.HasOne(ur => ur.Roles)
.WithMany(r => r.UserRoles)
.HasForeignKey(ur => ur.UserId);
}
5:创建新模型并更新数据库,您可能必须删除现有模型
6:如果要在用户中包含角色,请执行类似的查询
var usersWithRoles = context.Set<User>().Include(u => u.UserRoles).ThenInclude(ur => ur.Roles);