【问题标题】:EF Codefirst GET Method Sub-models not comingEF Codefirst GET 方法子模型不来
【发布时间】:2019-05-17 11:16:34
【问题描述】:

EF Codefirst GET 方法子模型未推出。 使用 Database First 我想要以下 Json 结果。但是,我无法使用 Code First 获得以下 Json。我需要一个结构来处理模型关系而不运行 include 方法。

模型.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
  }
]

【问题讨论】:

  • return db.Blogs.Include(x =&gt; x.Posts).ToList(); 以加载内部集合
  • @VidmantasBlazevicius 他在他的帖子中说“没有运行包含”,但不知道为什么不运行:p
  • 您好,上面的例子是一个简单的构建,原来构建的子表太多了。因此,我希望子模型在我首先调用数据库中的上层模型时自动出现。
  • 为了所有美好的圣物的爱,不要偷懒。对于每个单独的关系,您最终会得到 N+1 个查询。

标签: c# asp.net-core ef-code-first asp.net-core-webapi ef-database-first


【解决方案1】:

默认情况下,EF 不会自动加载关系,因为这需要 SQL JOIN,这在大多数情况下是不需要的 - 只有当您实际上需要相关数据时。

因此,您有两个选择:使用Include 急切地加载关系,或依赖延迟加载来查询相关数据,在访问时及时。默认情况下不启用延迟加载,因为坦率地说它有点反模式,除非您充分了解其影响和可能的问题,否则您不应该使用它。

在这种特殊情况下,那些可能出现的问题会迅速而戏剧性地抬头。由于您正在序列化实体,序列化程序将触及每个关系,导致单独发出查询以获取一组特定的相关数据。然后,您正在迭代的每个博客也会发生这种情况。而且,如果任何相关项目本身具有相关的事物,您将发出指数级的附加查询。简而言之,像这样的延迟加载可能会导致同时发出 100 个甚至数千个或更多查询 - 至少你不想发生这种情况。

简而言之,您需要急切地加载您关心的关系,无论这是否是您的首选方法。这里没有免费的午餐。它要么是一次查询所有连接,要么是稍后单独对每条数据进行大量查询。

或者,您可以考虑使用 OData 或 GraphQL 之类的东西。仅此一项并不能解决问题:默认情况下,相关项目将不包括在内。但是,这两者都提供了请求相关数据作为请求的一部分的能力,允许客户端仅检索他们需要或感兴趣的关系。这解决了您不想同时指定和查询每个关系的问题,同时仍然为客户提供了一种在他们需要/想要的时候轻松获取它的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    相关资源
    最近更新 更多