我有一种情况,需要为 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 次并在内存中过滤结果。
首先从客户状态中选择所有数据,然后从状态中选择所有数据,然后从客户中选择所有数据,然后过滤内存中的所有数据。有没有其他有效的方法来做到这一点?
这就是我通过实体类准备的方式
最佳答案
正如@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/