EF创建额外的外键列
EF create additional foreign key column
在我的应用程序中,用户可以编写 posts。更重要的是,每个用户都可以拥有 0 或 1 个收藏夹 post。我想要这样的数据库模式:
dbo.users
+----+--------+-----------------+
| Id | Name | FavouritePostId |
+----+--------+-----------------+
| 1 | Adam | 1 |
| 2 | Daniel | 2 |
| 3 | Aaron | null |
+----+--------+-----------------+
dbo.posts
+----+---------+--------+
| Id | Content | UserId |
+----+---------+--------+
| 1 | Hello | 1 |
| 2 | World | 1 |
| 3 | foo | 2 |
+----+---------+--------+
这意味着:
- Adam 是 posts
1,2
的创造者,他最喜欢的 post 是 post.id = 1
- Daniel 是 post
3
的创造者,他最喜欢的 post 是 post.id = 2
。
- Aaron 没有添加任何内容 post 并标记为收藏
我想用 Entity Framework 代码优先方法创建它。
这些是我的实体:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Post> Posts { get; set; }
[ForeignKey("FavouritePost")]
public int? FavouritePostId { get; set; }
public Post FavouritePost { get; set; }
}
public class Post
{
public int Id { get; set; }
public string Content { get; set; }
[ForeignKey("User")]
public int UserId { get; set; }
public User User { get; set; }
}
但我最终得到了 table:
dbo.posts
+----+---------+--------+---------+
| Id | Content | UserId | User_Id |
+----+---------+--------+---------+
如何删除额外的 User_Id
列?
你必须修复一些关系
public class User
{
public int Id { get; set; }
public string Name { get; set; }
[InverseProperty(nameof(Post.User))]
public virtual ICollection<Post> Posts { get; set; }
public int? FavouritePostId { get; set; }
[ForeignKey("FavouritePostId")]
[InverseProperty("Users")]
public virtual Post FavouritePost { get; set; }
}
public class Post
{
public int Id { get; set; }
public string Content { get; set; }
public int UserId { get; set; }
[ForeignKey("UserId")]
[InverseProperty("Posts")]
public virtual User User { get; set; }
[InverseProperty(nameof(User.FavouritePost))]
public virtual ICollection<User> Users { get; set; }
}
但我只想添加
public bool IsFavorite {get; set;}
到Postclass
Serge 的回答基本上涵盖了这个问题。为了对此进行扩展,部分问题是您使用“Id”作为用户的 PK。这里的问题是,当 EF 将 Post 关联到用户时,“Id”PK 将自然地变为 FK 名称的“User_Id”。解决方案是给 EF 一个 hint/configuration 什么应该用作 FK(InverseProperty 或显式映射),或者使用“UserId”作为 User 中的 PK 应该让它与 FK 自动配对 属性 在 Post.
对于 EF6,如果您确实希望将“Id”保留为用户中的 PK,则配置选项(通过 OnModelCreating()
或使用 EntityTypeConfiguration
)将为:
modelBuilder.Entity<Post>()
.HasOne(p => p.User)
.WithMany(u => u.Posts)
.HasForeignKey(p => p.UserId);
我同意将 Posts 和 FavoritePost 作为导航属性通常是不明智的。无法限制数据完整性,因为 FavoritePostId 将指向实际与该用户关联的 Post。 (用户 #1 上的 FavoritePost 引用可以合法地指向 UserId 为 2 的 Post。)替代方法是使用类似“IsFavorite”标志的东西,但是它有类似的问题没有限制只有 1 post 被标记为收藏夹(如果有)。另一种选择是给 Posts 一个 Rank 作为唯一约束 /w the UserId。这样您的业务逻辑就可以确定最喜欢的是排名最低或最高的post。
在我的应用程序中,用户可以编写 posts。更重要的是,每个用户都可以拥有 0 或 1 个收藏夹 post。我想要这样的数据库模式:
dbo.users
+----+--------+-----------------+
| Id | Name | FavouritePostId |
+----+--------+-----------------+
| 1 | Adam | 1 |
| 2 | Daniel | 2 |
| 3 | Aaron | null |
+----+--------+-----------------+
dbo.posts
+----+---------+--------+
| Id | Content | UserId |
+----+---------+--------+
| 1 | Hello | 1 |
| 2 | World | 1 |
| 3 | foo | 2 |
+----+---------+--------+
这意味着:
- Adam 是 posts
1,2
的创造者,他最喜欢的 post 是post.id = 1
- Daniel 是 post
3
的创造者,他最喜欢的 post 是post.id = 2
。 - Aaron 没有添加任何内容 post 并标记为收藏
我想用 Entity Framework 代码优先方法创建它。 这些是我的实体:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Post> Posts { get; set; }
[ForeignKey("FavouritePost")]
public int? FavouritePostId { get; set; }
public Post FavouritePost { get; set; }
}
public class Post
{
public int Id { get; set; }
public string Content { get; set; }
[ForeignKey("User")]
public int UserId { get; set; }
public User User { get; set; }
}
但我最终得到了 table:
dbo.posts
+----+---------+--------+---------+
| Id | Content | UserId | User_Id |
+----+---------+--------+---------+
如何删除额外的 User_Id
列?
你必须修复一些关系
public class User
{
public int Id { get; set; }
public string Name { get; set; }
[InverseProperty(nameof(Post.User))]
public virtual ICollection<Post> Posts { get; set; }
public int? FavouritePostId { get; set; }
[ForeignKey("FavouritePostId")]
[InverseProperty("Users")]
public virtual Post FavouritePost { get; set; }
}
public class Post
{
public int Id { get; set; }
public string Content { get; set; }
public int UserId { get; set; }
[ForeignKey("UserId")]
[InverseProperty("Posts")]
public virtual User User { get; set; }
[InverseProperty(nameof(User.FavouritePost))]
public virtual ICollection<User> Users { get; set; }
}
但我只想添加
public bool IsFavorite {get; set;}
到Postclass
Serge 的回答基本上涵盖了这个问题。为了对此进行扩展,部分问题是您使用“Id”作为用户的 PK。这里的问题是,当 EF 将 Post 关联到用户时,“Id”PK 将自然地变为 FK 名称的“User_Id”。解决方案是给 EF 一个 hint/configuration 什么应该用作 FK(InverseProperty 或显式映射),或者使用“UserId”作为 User 中的 PK 应该让它与 FK 自动配对 属性 在 Post.
对于 EF6,如果您确实希望将“Id”保留为用户中的 PK,则配置选项(通过 OnModelCreating()
或使用 EntityTypeConfiguration
)将为:
modelBuilder.Entity<Post>()
.HasOne(p => p.User)
.WithMany(u => u.Posts)
.HasForeignKey(p => p.UserId);
我同意将 Posts 和 FavoritePost 作为导航属性通常是不明智的。无法限制数据完整性,因为 FavoritePostId 将指向实际与该用户关联的 Post。 (用户 #1 上的 FavoritePost 引用可以合法地指向 UserId 为 2 的 Post。)替代方法是使用类似“IsFavorite”标志的东西,但是它有类似的问题没有限制只有 1 post 被标记为收藏夹(如果有)。另一种选择是给 Posts 一个 Rank 作为唯一约束 /w the UserId。这样您的业务逻辑就可以确定最喜欢的是排名最低或最高的post。