簡體   English   中英

如何最有效地獲取實體框架中相關實體的最大值

[英]How to get max value of related entity in Entity Framework most effectively

我想獲取類別中具有最新產品的類別列表。

我正在使用Entity Framework Core 2.1。

我已經嘗試過了,但是速度很慢

var categories = context.Categories.Select(x => new {
    x.Id,
    Product = x.Products.OrderByDescending(y => y.Date).Select(y => y.Name).FirstOrDefault()
}

該LINQ查詢應生成單個SQL查詢,該查詢應該很快。

就像是:

SELECT [t].[CategoryId], (
    SELECT TOP(1) [r].[Name]
    FROM [Products] AS [r]
    WHERE [t].[CategoryId] = [r].[CategoryId]
    ORDER BY [r].[Date] DESC
) AS [FirstName]
FROM [Categorys] AS [t]

這是一個包含100個類別的示例,每個類別都有1000種要測試的產品。 代碼優先將在Product.CategoryId上創建索引,但是即使沒有索引,這也不是一個昂貴的查詢。

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
using System.Data.SqlClient;
using System.Linq;

namespace EfCoreTest
{

    public class Category
    {
        public int CategoryId { get; set; }
        public virtual ICollection<Product> Readings { get; } = new HashSet<Product>();
    }
    public class Product
    {
        public int ProductId{ get; set; }
        public string Name { get; set; }
        public DateTime Date { get; set; }
        public Category Category { get; set; }


    }

    public class Db : DbContext
    {
        public DbSet<Category> Categorys { get; set; }
        public DbSet<Product> Products { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("server=.;database=EfCoreTest;Integrated Security=true");
            base.OnConfiguring(optionsBuilder);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }
    }

    class Program
    {

        static void Main(string[] args)
        {

            using (var db = new Db())
            {

                db.Database.EnsureDeleted();
                db.Database.EnsureCreated();

                for (int i = 0; i < 100; i++)
                {
                    var t = new Category();

                    for (int j = 0; j < 1000; j++)
                    {
                        var product = new Product()
                        {
                            Category = t,
                            Date = DateTime.Now,
                            Name = $"Category {j}{i}"

                        };
                        db.Add(product);
                    }
                    db.Add(t);


                }
                db.SaveChanges();



            }
            using (var db = new Db())
            {
                var q = db.Categorys.Select(t => new
                {
                    t.CategoryId,
                    FirstName = t.Readings.OrderByDescending(r => r.Date).Select(r => r.Name).FirstOrDefault()
                });

                var l = q.ToList();

                Console.WriteLine("Hit any key to exit.");
                Console.ReadKey();

            }

        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM