EF Codefirst GET方法子模型不存在。 使用数据库优先,我想要以下Json结果。但是,我无法通过 Code First 获得以下Json。我需要一种结构来处理模型关系,而无需运行include方法。
Model.cs
public class BloggingContext : DbContext
{
public BloggingContext(DbContextOptions<BloggingContext> options) : base(options){ }
public virtual DbSet<Blog> Blogs { get; set; }
public virtual DbSet<Post> Posts { get; set; }
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public ICollection<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
ValuesController.cs
private readonly BloggingContext db;
public ValuesController(BloggingContext db)
{
this.db = db;
}
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<Blog>> Get()
{
return db.Blogs.ToList();
}
Startup.cs
var connection = @"Server=(localdb)\mssqllocaldb;Database=EFGetStarted.AspNetCore.NewDb;Trusted_Connection=True;ConnectRetryCount=0";
services.AddDbContext<Models.Model.BloggingContext>
(options => options.UseSqlServer(connection));
数据库表
Blogs Table Result
__________________
BlogId | Url
1 | asdasd1
2 | asdas2
Posts Table Result
__________
PostId | Title | Content | BlogId
1 | asdasd | fdg | 1
2 | fsg | asda | 1
3 | dsgfsdg | sgf | 2
运行结果
[
{
"blogId": 1,
"url": "asdasd1",
"posts": null
},
{
"blogId": 2,
"url": "asdas2",
"posts": null
},
{
"blogId": 3,
"url": "asdsad3",
"posts": null
}
]
我想使用以上代码
[
{
"blogId": 1,
"url": "asdasd1",
"posts": [
{
"PostId": 1,
"Title": "asdasd",
"Content": "fdg"
},
{
"PostId": 2,
"Title": "fsg",
"Content": "asda"
}
]
},
{
"blogId": 2,
"url": "asdas2",
"posts": {
"PostId": 2,
"Title": "fsg",
"Content": "asda"
}
},
{
"blogId": 3,
"url": "asdsad3",
"posts": null
}
]
答案 0 :(得分:0)
默认情况下,EF不会自动加载关系,因为这将需要SQL JOIN,这在大多数情况下都是不希望的-仅当您实际上想要相关数据时。
因此,您有两个选择:急于使用Include
加载关系,或依靠延迟加载在访问时及时查询相关数据。延迟加载默认情况下未启用,因为坦率地说它有点反模式,除非您充分了解其影响和可能的问题,否则不应该使用它。
在这种特定情况下,那些可能出现的问题将迅速而戏剧性地抬起头来。由于您要对实体进行序列化,因此序列化程序将处理每个关系,从而导致单独发出查询以获取一组特定的相关数据。然后,您要遍历的每个博客也会发生这种情况。而且,如果任何相关项目本身具有相关的内容,那么您将要发出指数级的附加查询。简而言之,如果不同时执行数千个或更多查询,那么像这样的延迟加载可能会导致100条查询-至少您不想发生这种事情。
简而言之,您需要急切地加载您关心的关系,无论这是否是您的首选方法。这里没有免费的午餐。这是一个查询,一次包含所有联接,或者稍后对每个数据块进行大量查询。
或者,您可以考虑使用OData或GraphQL之类的东西。仅凭这一点并不能解决问题:默认情况下,不会包含相关项。但是,这两种功能都可以将相关数据作为请求的一部分进行请求,从而允许客户端仅检索他们需要或感兴趣的关系。这解决了您不希望一次指定和查询所有单个关系的问题,同时仍然为客户提供了在需要/需要时可以轻松获得的方法。