英文:
Understanding EF Core Relationships: Why Include public int BlogId { get; set; } and public Blog Blog { get; set; } in the Post Class?
问题
我一直在使用Entity Framework Core,并且正在努力更好地理解关系。我有两个类,Blog
和Post
,它们定义了一个一对多的关系,其中一个Blog
包含多个Post
实体。
以下是简化的类定义:
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Uri SiteUri { get; set; }
public ICollection<Post> Posts { get; }
}
public class Post
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public DateTime PublishedOn { get; set; }
public bool Archived { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
我对Post
类中的
public int BlogId { get; set; }
和
public Blog Blog { get; set; }
属性的存在感到困惑。据我了解,这两个属性不会直接迁移到数据库作为列。为什么在这个关系定义中需要它们?
我正在考虑在Stack Overflow上提出这个问题,以澄清我的理解。是否有人可以解释一下包含这些属性的原因,它们在关系中的作用以及它们如何增强Entity Framework Core的体验?
非常感谢您提前的帮助!
英文:
I have been working with Entity Framework Core and I'm trying to understand relationships better. I have two classes, Blog
and Post
, which define a one-to-many relationship where a Blog
contains multiple Post
entities.
Here are the simplified class definitions:
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Uri SiteUri { get; set; }
public ICollection<Post> Posts { get; }
}
public class Post
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public DateTime PublishedOn { get; set; }
public bool Archived { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
My confusion arises from the presence of the
public int BlogId { get; set; }
and
public Blog Blog { get; set; }
properties in the Post
class. As far as I understand, these two properties are not directly migrated to the database as columns. Why are they necessary in this relationship definition?
I'm considering asking this question on Stack Overflow to clarify my understanding. Could someone provide an explanation for including these properties, their roles in the relationship, and how they enhance the Entity Framework Core experience?
Any insights would be greatly appreciated!
Thank you in advance for your help!
答案1
得分: 2
据我理解,这两个属性并不直接作为列迁移到数据库中。为什么在这个关系定义中它们是必要的?
BlogId
被添加为一个列。它将用于建立关系,并且将作为外键(在关系型数据库中)使用。实际上,指定 BlogId
是不必要的,只需添加以下代码即可:
public Blog Blog { get; set; }
就足够了,EF Core 将创建相应的列(但个人偏好将其公开,因为在某些情况下它很有用)。
例如,在 SQL Server 中,它应该生成类似以下的 SQL 语句:
CREATE TABLE [Posts] (
[Id] int NOT NULL IDENTITY,
[Title] nvarchar(max) NULL,
[Content] nvarchar(max) NULL,
[PublishedOn] datetime2 NOT NULL,
[Archived] bit NOT NULL,
[BlogId] int NOT NULL,
CONSTRAINT [PK_Posts] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Posts_Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blogs] ([Id]) ON DELETE CASCADE);
在这个关系定义中,它们为什么是必要的?
理论上,你可以省略这两个属性,并通过 fluent 接口来设置关系,但通常认为拥有导航属性是一种良好的实践,这样你就可以简化你的工作,使用它们而不是编写“手动”连接来过滤或加载相关数据。例如,以下代码:
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ToList();
应该会生成适当的 SQL 语句,并填充所需的数据以便于使用。
参考资料/阅读:
英文:
> As far as I understand, these two properties are not directly migrated to the database as columns. Why are they necessary in this relationship definition?
BlogId
is added as a column. It will be used to setup the relationship and will be used as foreign key (in relational database). Actually specifying BlogId
is not required, just adding:
public Blog Blog { get; set; }
Is enough, EF Core will create corresponding columns (but personally I prefer to expose it due to it being useful in some cases).
For example in SQL Server it should result in something like the following:
CREATE TABLE [Posts] (
[Id] int NOT NULL IDENTITY,
[Title] nvarchar(max) NULL,
[Content] nvarchar(max) NULL,
[PublishedOn] datetime2 NOT NULL,
[Archived] bit NOT NULL,
[BlogId] int NOT NULL,
CONSTRAINT [PK_Posts] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Posts_Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blogs] ([Id]) ON DELETE CASCADE);
> Why are they necessary in this relationship definition?
In theory you can omit both properties and setup the relationship via fluent interface, but in general having the navigation property is considered a good practice, so you will simplify your life and use them instead of writing "manual" joins to filter or load related data. For example the following:
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ToList();
Should generate appropriate SQL with joins and fill the needed data for the ease of use.
Sources/read also:
答案2
得分: 0
首先,你应该在BlogId上添加注解[ForeignKey(nameof(this.Blog))],或者在你的上下文的modelCreating中使用fluent API来描述关系。
通过这样做,如果你使用的是Code First方法,EF将在数据库中创建关系。
然后,Blog属性被称为导航属性,它是告诉EF如何双向映射相关实体的方式。
所以在你的查询中:
Var posts = ctx.Post.Include(x => x.Blog).ToList()
你将连接博客和帖子。
每当你访问一个帖子对象,比如:
posts[0]
通过这样做,你将直接访问该帖子的博客对象:
posts[0].Blogs,它是一个博客列表。
这就是导航属性的作用和存在的原因。
我建议你在开始编码之前阅读一本EF初学者的书籍,这样你就能更好地理解EF是什么,以及它与数据库的关系!
英文:
First of all you should add the annotation [ForeignKey(nameof(this.Blog))
] on BlogId or describe the relation ship with fluent API on modelCreating from your context.
By doing this the ef will create the relatioship on the database if you are using the code first approach.
Then the Blog property is called as a navigation property and is the way to tell ef to map the related entity both ways.
So in your query:
Var posts = ctx.Post.Include(x => x.Blog).ToList() you will join the blog to the post.
Whenever you access a post object, lets say:
posts[0]
You will have a direct access to your blog objects of this post by doing this:
posts[0].Blogs which is a list o blogs
And thats the navigation property and the reason why is there.
I suggest that you start reading a book for ef for beginners before starting coding so you have a better understanding for what the ef it is and the relation it has with the db!!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论