我有一种情况,需要为 Include 对象完成 OrderBy。这是我迄今为止尝试过的方式

Customers query = null;

try
{
    query = _context.Customers
        .Include(x => x.CustomerStatus)
        .ThenInclude(x => x.StatusNavigation)
        .Select(x => new Customers()
        {
            Id = x.Id,
            Address = x.Address,
            Contact = x.Contact,
            Name = x.Name,
            CustomerStatus = new List<CustomerStatus>
            {
                x.CustomerStatus.OrderByDescending(y => y.Date).FirstOrDefault()
            }
        })
        .FirstOrDefault(x => x.Id == 3);
}
catch (Exception ex)
{
    throw;
}

上面的代码成功地对 include 元素进行了排序,但不包括它的子表。
例如:客户包括 CustomerStatus 但 CustomerStatus 不包括 StatusNavigation 表。

我什至尝试过这个,但它都不能帮助我
_context.Customers
    .Include(x => x.CustomerStatus.OrderByDescending(y => y.Date).FirstOrDefault())
    .ThenInclude(x => x.StatusNavigation).FirstOrDefault(x => x.Id == 3);

我做错了什么请指导我

即使我试过这种方式
var query = _context.CustomerStatus
    .GroupBy(x => x.CustomerId)
    .Select(x => x.OrderByDescending(y => y.Date).FirstOrDefault())
    .Include(x => x.StatusNavigation)
    .Join(_context.Customers, first => first.CustomerId, second => second.Id, (first, second) => new Customers
    {
        Id = second.Id,
        Name = second.Name,
        Address = second.Address,
        Contact = second.Contact,
        CustomerStatus = new List<CustomerStatus> {
            new CustomerStatus
            {
                Id = first.Id,
                CustomerId = first.CustomerId,
                Date = first.Date,
                StatusNavigation = first.StatusNavigation
            }
        },
    }).FirstOrDefault(x => x.Id == 3);

但这是命中数据库 3 次并在内存中过滤结果。
首先从客户状态中选择所有数据,然后从状态中选择所有数据,然后从客户中选择所有数据,然后过滤内存中的所有数据。有没有其他有效的方法来做到这一点?

这就是我通过实体类准备的方式
c# - Linq - 包含的顺序-LMLPHP

最佳答案

正如@Chris Pratt 提到的,一旦您在 select 中执行 new Customer ,您就会创建一个新模型。您正在丢弃由 EntityFramework 构建的模型。我的建议是查询只是:

query = _context.Customers
    .Include(x => x.CustomerStatus)
    .ThenInclude(x => x.StatusNavigation);

像这样,您将拥有一个 IQueryable 对象,除非您从中进行选择,否则它不会被执行:
var customer3 = query.FirstOrDefault(x=>x.Id==3)

它返回客户和相互关联的表(CustomerStatus 和 StatusNavigation)。然后你可以创建你想要的对象:
var customer = new Customers()
    {
        Id = customer3.Id,
        Address = customer3.Address,
        Contact = customer3.Contact,
        Name = x.Name,
        CustomerStatus = new List<CustomerStatus>
        {
            customer3.CustomerStatus.OrderByDescending(y => y.Date).FirstOrDefault()
        }
    })

通过这种方式,您可以重用查询来创建不同的响应对象并对数据库进行单个查询,但缺点是使用的内存比原始查询多(即使它不应该是太大的问题)。

如果最初从数据库返回的模型不符合要求(即您总是需要执行: CustomerStatus = new List {...} ),则可能表明数据库模式没有很好地定义为满足需求应用程序,因此可能需要重构。

关于c# - Linq - 包含的顺序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58102597/

10-13 06:53