C# 访问多对多连接实体的属性';导航属性
我在C# 访问多对多连接实体的属性';导航属性,c#,sql-server,asp.net-mvc,asp.net-core,C#,Sql Server,Asp.net Mvc,Asp.net Core,我在Post和Tag之间有一个多对多关系,由连接实体PostTag表示。我目前能够访问Post类的Details视图中的PostTag表;例如,我可以查看特定的Post,并显示相关的PostTags。但是,我只能显示PostTag属性PostId和TagId,而我想通过PostTag实体显示与Tag类相关的属性 有一些在线的详细方法可以显示多对多的关系,但它们似乎都与我所采用的方法大不相同,因此似乎不容易翻译到我的项目中 型号 public class Post { pu
Post
和Tag
之间有一个多对多关系,由连接实体PostTag
表示。我目前能够访问Post
类的Details
视图中的PostTag
表;例如,我可以查看特定的Post
,并显示相关的PostTags
。但是,我只能显示PostTag
属性PostId
和TagId
,而我想通过PostTag
实体显示与Tag
类相关的属性
有一些在线的详细方法可以显示多对多的关系,但它们似乎都与我所采用的方法大不相同,因此似乎不容易翻译到我的项目中
型号
public class Post
{
public int Id { get; set; } // primary key
public string Title { get; set; }
public string Description { get; set; }
public DateTime PublicationDate { get; set; }
public ICollection<PostTag> PostTags { get; } = new List<PostTag>();
}
public class Tag
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public ICollection<PostTag> PostTags { get; } = new List<PostTag>();
}
public class PostTag
{
public int PostId { get; set; }
public Post post { get; set; }
public int TagId { get; set; }
public Tag tag { get; set; }
}
我似乎无法访问标记.Title
;例如,@Html.DisplayFor(modelItem=>postTag.tag.Title)
不显示任何视图。我期望的输出是,假设标签
行的小说
,非小说
和经典
的Id
值等于2
,4
和5
Fiction
Nonfiction
Classic
谢谢你的建议
编辑:
在调试模式下加载详细信息页面时,post
变量包含所有预期属性,包括PostTags
PostTags
包含预期数量的元素(三个PostTag
元素,因为此Post
实例有三个关联的Tags
)。每个元素都包含PostId
、TagId
、post
和tag
的属性;但是,tag
是null
。这就是问题所在,因为我正在尝试访问tag.Title
。局部变量的屏幕截图如下:
您可以使用该方法包含多个级别的相关数据 多对多数据库上下文:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(builder);
modelBuilder.Entity<PostTag>()
.HasKey(pt => new { pt.PostId, pt.TagId });
modelBuilder.Entity<PostTag>()
.HasOne(pt => pt.Post)
.WithMany(p => p.PostTags)
.HasForeignKey(pt => pt.PostId);
modelBuilder.Entity<PostTag>()
.HasOne(pt => pt.Tag)
.WithMany(t => t.PostTags)
.HasForeignKey(pt => pt.TagId);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
基于模型创建(生成器);
modelBuilder.Entity()
.HasKey(pt=>new{pt.PostId,pt.TagId});
modelBuilder.Entity()
.HasOne(pt=>pt.Post)
.WithMany(p=>p.PostTags)
.HasForeignKey(pt=>pt.posted);
modelBuilder.Entity()
.HasOne(pt=>pt.Tag)
.WithMany(t=>t.posttag)
.HasForeignKey(pt=>pt.TagId);
}
请参阅您可以使用该方法包含多个级别的相关数据 多对多数据库上下文:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(builder);
modelBuilder.Entity<PostTag>()
.HasKey(pt => new { pt.PostId, pt.TagId });
modelBuilder.Entity<PostTag>()
.HasOne(pt => pt.Post)
.WithMany(p => p.PostTags)
.HasForeignKey(pt => pt.PostId);
modelBuilder.Entity<PostTag>()
.HasOne(pt => pt.Tag)
.WithMany(t => t.PostTags)
.HasForeignKey(pt => pt.TagId);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
基于模型创建(生成器);
modelBuilder.Entity()
.HasKey(pt=>new{pt.PostId,pt.TagId});
modelBuilder.Entity()
.HasOne(pt=>pt.Post)
.WithMany(p=>p.PostTags)
.HasForeignKey(pt=>pt.posted);
modelBuilder.Entity()
.HasOne(pt=>pt.Tag)
.WithMany(t=>t.posttag)
.HasForeignKey(pt=>pt.TagId);
}
请参阅try.Include(p=>PostTags.Tag)。另外,请检查上下文中是否启用了延迟加载。应该行的。谢谢你的评论。在
Include()
调用中,我似乎无法从PostTags
访问任何其他属性。我不确定什么是延迟加载,请看一看。我现在将编辑我的帖子以包含我的上下文。@heds1如果您不熟悉LINQ
语法,请尝试使用LINQ Query
语法。这样,您就可以根据需要定义联接。教程可以在这里找到:@RahulSharma嗨,谢谢你的评论。我的理解是,控制器正在使用LINQ访问PostTags
(var post=await\u context.post.Include(p=>p.PostTags).FirstOrDefaultAsync(m=>m.Id==Id);
)。我的问题是,我不确定如何访问导航属性Tag
,以及它的属性Title
@heds1您是否能够在您的Post
模型中获得所需的数据,特别是在您的icollettionPostTags
中。您是否尝试过调试并查看您的查询是否返回了所需的数据?try.Include(p=>PostTags.Tag)。另外,请检查上下文中是否启用了延迟加载。应该行的。谢谢你的评论。在Include()
调用中,我似乎无法从PostTags
访问任何其他属性。我不确定什么是延迟加载,请看一看。我现在将编辑我的帖子以包含我的上下文。@heds1如果您不熟悉LINQ
语法,请尝试使用LINQ Query
语法。这样,您就可以根据需要定义联接。教程可以在这里找到:@RahulSharma嗨,谢谢你的评论。我的理解是,控制器正在使用LINQ访问PostTags
(var post=await\u context.post.Include(p=>p.PostTags).FirstOrDefaultAsync(m=>m.Id==Id);
)。我的问题是,我不确定如何访问导航属性Tag
,以及它的属性Title
@heds1您是否能够在您的Post
模型中获得所需的数据,特别是在您的icollettionPostTags
中。您是否尝试过调试并查看您的查询是否返回了所需的数据?我缺少的是正确地应用ModelBuilder
。非常感谢。非常棒,正确应用ModelBuilder
是我所缺少的。谢谢。
PostId
1
TagId
2
PostId
1
TagId
4
PostId
1
TagId
5
Fiction
Nonfiction
Classic
var post= await _context.Post
.Include(p => p.Author)
.Include(p => p.PostTags)
.ThenInclude(pt => pt.Tag)
.FirstOrDefaultAsync(p => p.Id == id);
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(builder);
modelBuilder.Entity<PostTag>()
.HasKey(pt => new { pt.PostId, pt.TagId });
modelBuilder.Entity<PostTag>()
.HasOne(pt => pt.Post)
.WithMany(p => p.PostTags)
.HasForeignKey(pt => pt.PostId);
modelBuilder.Entity<PostTag>()
.HasOne(pt => pt.Tag)
.WithMany(t => t.PostTags)
.HasForeignKey(pt => pt.TagId);
}