EntityFramework始终创建新的关系表记录



我是EntityFramework的新手。我的代码如下。

用户.cs

public User 
{
    public long Id { get; set; }
    public long UserRoleId { get; set; }
    public string Name { get; set; }
    public virtual UserRole UserRole { get; set; }
}
public class UserMap : EntityTypeConfiguration<User> 
{
    public UserMap()
    {
        ToTable("User");
        HasKey(x => x.Id);
        HasRequired(x => x.UserRole)
            .WithMany(x => x.Users)
            .HasForeignKey(x => x.UserRoleId);
    }
}

UserRole.cs

public UserRole 
{
    public long Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<User> Users { get; set; }
    public UserRole()
    {
        Users = new List<User>();
    }
}
public class UserRoleMap : EntityTypeConfiguration<UserRole>
{
    public UserRoleMap()
    {
        ToTable("UserRole");
        HasKey(x => x.Id);
    }
}

安装.cs

public Install
{
    public static void Install()
    {
        RpUserRoles.Create(new UserRole() { Name = "System" });
        RpUserRoles.Create(new UserRole() { Name = "Admin" });
        var roleSystem = RpUserRoles.Table.Where(x => x.Name.Equals("System")).FirstOrDefault();
        User userSystem = new User();
        userSystem.Name = "UserSystem";
        userSystem.UserRole = roleSystem;
        RpUser.Create(userSystem);
        var roleAdmin = RpUserRoles.Table.Where(x => x.Name.Equals("Admin")).FirstOrDefault();
        User userAdmin = new User();
        userAdmin.Name = "UserAdmin";
        userAdmin.UserRoleId = roleAdmin.Id;
        RpUser.Create(userAdmin);
    }
}

当我在数据库中创建新用户时,数据库中得到的结果是错误的。EntityFramework与关系表中的记录重复。结果为

User
| Id | UserRoleId | Name       |
|  1 |          3 | UserSystem |
|  2 |          2 | UserAdmin  |
UserRole
| Id | Name   |
|  1 | System |
|  2 | Admin  |
|  3 | System |

UserSystem用户的预期UserRoleId应为1,但我不知道为什么EntityFramework会在UserRole表中复制新记录。由于UserAdmin设置了UserRoleId,因此应该可以。我可以知道我配置错了吗?谢谢

如果您创建了UserRole(即RpUserRoles.Create(new UserRole() { Name = "System" }))并从不同的上下文中检索它(RpUserRoles.Table.Where(x => x.Name.Equals("System")).FirstOrDefault()),就会发生这种情况。实体框架不会知道它们是相同的,所以它会把第二个当作新的。看起来你正在使用一个围绕实体框架的包装器(RpUserRoles.Create,RpUserRoles.Table);它是如何处理上下文的?它是否为每个方法创建一个?

您的代码应该是这样的

    var roleSystem=RpUserRoles.Create(new UserRole() { Name = "System" });
    var rolAdmin=RpUserRoles.Create(new UserRole() { Name = "Admin" });
    //var roleSystem = RpUserRoles.Table.Where(x => x.Name.Equals("System")).FirstOrDefault();
    User userSystem = new User();
    userSystem.Name = "UserSystem";
    userSystem.UserRole = roleSystem;
    RpUser.Create(userSystem);
    //var roleAdmin = RpUserRoles.Table.Where(x => x.Name.Equals("Admin")).FirstOrDefault();
    User userAdmin = new User();
    userAdmin.Name = "UserAdmin";
    userAdmin.UserRoleId = roleAdmin.Id;
    RpUser.Create(userAdmin);

DbSet<T>.Create的定义是:为该集合的类型创建实体的新实例。请注意,此实例未添加或附加到集合中。如果底层上下文配置为创建代理,并且实体类型满足创建代理的要求,则返回的实例将是代理。

所以我认为你应该在上下文中添加roleSystem和roleAdmin

希望这将帮助您

最新更新