【问题标题】:One-to-one relationship in CF Entity Framework using mappingCF Entity Framework 中使用映射的一对一关系
【发布时间】:2013-06-04 15:10:09
【问题描述】:

我正在使用 Entity Framework 5,代码优先。

我有两个域对象(或表)。第一个是User,第二个是UserProfile。一个用户只能拥有一个配置文件,一个配置文件只属于一个用户。那是1-1的关系。

这是类....(我简化了代码以使其易于理解,实际上更复杂)

用户

public class User {
    public virtual Int64 UserId { get; set; }
    public virtual UserProfile UserProfile { get; set; }
    public virtual String Username{ get; set; }
    public virtual String Email { get; set; }
    public virtual String Password { get; set; }
}

用户资料

public class UserProfile {
    public virtual Int64 UserId { get; set; }
    public virtual User User { get; set; }
    public virtual Int64 Reputation { get; set; }
    public virtual String WebsiteUrl { get; set; }
}

这是地图......

用户地图

public UserMap() {
    this.Property(t => t.Email)
        .IsRequired()
        .HasMaxLength(100);
    this.Property(t => t.Password)
        .IsRequired()
        .HasMaxLength(15);
    this.Property(t => t.Username)
        .IsRequired()
        .HasMaxLength(15);
}

UserProfileMap

public UserProfileMap()
    {
        this.HasKey(t => t.UserId);
    }

这里是上下文....

public class TcContext : DbContext {
    static TcContext () {
        Database.SetInitializer(new TcContextInitializer());
    }
    public DbSet<User> Users { get; set; }
    public DbSet<UserProfile> UserProfiles { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Configurations.Add(new UserMap());
        modelBuilder.Configurations.Add(new UserProfileMap());
    }
}

这是我的错误信息....

Unable to determine the principal end of an association between the types 'Tc.Domain.UserProfile' and 'Tc.Domain.User'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

我认为EF应该以这种方式自动确定关系。但它给了我上面的错误信息。我已经研究了这个问题一段时间,但在我的案例中找不到一个很好的说明。

我的错误在哪里?或者,我应该在地图中定义某种额外的关系吗?

【问题讨论】:

  • 关系属性在哪里?
  • @ElvinArzumanoğlu 你的意思是 .HasRequired(t => t.User) 和 .WithRequiredPrincipal(); ?那里有,但我删除了它们,因为它们没有解决问题。
  • @ElvinArzumanoğlu,实际上当我把 .HasRequired(t => t.User) 和 .WithRequiredPrincipal();它正在创建一对多关系,就像一个用户可以拥有许多个人资料一样。实际上并非如此。每个用户只有一个配置文件。

标签: c# asp.net-mvc-4 ef-code-first entity-framework-5


【解决方案1】:

我不得不修改UserMap类如下

public UserMap() {
    this.Property(t => t.Email)
        .IsRequired()
        .HasMaxLength(100);
    this.Property(t => t.Password)
        .IsRequired()
        .HasMaxLength(15);
    this.Property(t => t.Username)
        .IsRequired()
        .HasMaxLength(15);
    this.HasOptional(t => t.UserProfile)
        .WithRequired(t => t.User);
}

它本质上说: “用户有一个可选的实体 UserProfile,而后者又具有一个必需的用户实体”

UserProfile中key的定义在这里是必须的。

【讨论】:

    【解决方案2】:

    刚刚又看了一遍,是否需要将 HasKey 添加到 UserMap 以便它知道哪个是密钥,否则您可以执行以下操作:-

    您是否可以将 UserProfile 更改为从 User 继承,然后将其添加到您的 OnModelCreating 方法中

    modelBuilder.Entity().ToTable("UserProfile");

    这将在数据库上创建您的一对一关系。我必须使用我当前的模型来做到这一点,否则如果你不指定 ToTable 部分,它会将它们集中到一个带有鉴别器列的表中

    干杯马克

    【讨论】:

      猜你喜欢
      • 2017-02-17
      • 1970-01-01
      • 2019-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-25
      相关资源
      最近更新 更多