我是否需要使用属性ClassId来表示代码优先(实体框架)中的关系

本文关键字:实体 框架 关系 代码 表示 是否 ClassId 属性 | 更新日期: 2023-09-27 18:18:43

我正在使用实体框架(代码优先)。

我想知道我是否真的需要使用一个属性与Id的关系与另一个实体如下面的代码。

public class User
{
    public int Id { get; set; }
    public string Login { get; set; }
    public string Password { get; set; }
    public int ProfileId { get; set; }
    public Profile Profile{ get; set; }
}
public class Profile
{
    public int Id { get; set; }
    public string Description{ get; set; }
}

这样,当我通过设置profileid属性插入用户时,执行得很好。

但是当我不使用Profile类中的profileid属性时,

public class User
{
    public int Id { get; set; }
    public string Login { get; set; }
    public string Password { get; set; }
    public Profile Profile{ get; set; }
}
public class Profile
{
    public int Id { get; set; }
    public string Description{ get; set; }
}

插入方法的执行添加了另一个概要文件记录。为什么?

我映射:

public class EntityMapping<Entity> : EntityTypeConfiguration<Entity> where Entity : EntityBase
{
    public EntityMapping()
    {
        HasKey(e => e.Id);
        Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }
}
public class UserMapping : EntityMapping<User>
{
    public UserMapping() : base()
    {
         ToTable("USER");
         Property(p => p.Id).HasColumnName("USER_CD_USER");
         Property(p => p.Login).HasColumnName("USER_TX_LOGIN").HasMaxLength(10).IsRequired();
         Property(p => p.Password).HasColumnName("USUA_TX_PASSWORD").HasMaxLength(8).IsRequired();
         HasRequired(e => e.Profile).WithMany(p => p.Users).Map(p => p.MapKey("PROF_CD_PROFILE"));
     }
}
public class ProfilelMapping : EntityMapping<Profile>
{
    public ProfileMapping()
        : base()
    {
        ToTable("PROFILE");
        Property(p => p.Id).HasColumnName("PROF_CD_PROFILE");
        Property(p => p.Description).HasColumnName("PROFILE_DS_PROFILE").HasMaxLength(20).IsRequired();
        HasMany(e => e.Users).WithRequired(p => p.Profile);
    }
}

我是否需要使用属性ClassId来表示代码优先(实体框架)中的关系

你问了两个问题。

我需要使用FK属性吗?

不,你没有,但EF的行为改变,如果你使用或不使用它。更多的信息在单独的答案和链接的博客文章中。

为什么EF再次插入Profile ?

与现有实体创建关系需要特别小心。EF不会检查你的实体是否存在于数据库中——你必须告诉EF。以下是实现这一目标的众多方法之一(无需从数据库加载配置文件):

var user = GetNewUserSomewhere();
context.Users.Add(user);
// Dummy profile representing existing one.
var profile = new Profile() { Id = 1 };
// Informing context about existing profile.
context.Profiles.Attach(profile);
// Creating relation between new user and existing profile
user.Profile = profile;
context.SaveChanges();

简短的回答:是的。这就是英孚的工作方式。它需要将外键存储在专用属性中。您是否曾经从数据库生成过类结构?它总是添加key属性。在某些情况下,您不需要加载Profile属性,但稍后可能需要检索它。这就是专用的ProfileId属性所使用的,它将从那里读取键值并加载对象。