在我的情况下,需要为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次访问,并在内存中过滤结果。首先从客户状态选择所有数据,然后从状态选择,然后从客户筛选内存中的所有数据。有没有其他有效的方法来做到这一点?
这就是我按实体类准备的方法。

发布于 2019-09-30 07:58:49
正如@Chris所提到的,一旦您在select中执行,新客户,您将创建一个新模型。您正在丢弃由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 = needs {.}),它可能表明数据库模式没有很好地定义以满足应用程序的需要,因此可能需要重构。
发布于 2019-09-25 16:49:39
我认为正在发生的事情是,您实际上正在重写Include和ThenInclude。Include显式地加载导航属性.然而,您正在做的一些事情可能会妨碍这一点。
首先,选择一个新的Customer。光是这一点就足以打破Include的逻辑。其次,您正在重写CustomerStatus集合中的内容。理想情况下,应该通过Include自动加载它,但通过修改它使其只具有第一个实体,实际上是在丢弃Include的效果。(选择关系就足以导致发出联接,而无需显式调用Include)。第三,ThenInclude是以Include为基础的,因此覆盖性很可能也会丢弃ThenIncude。
所有这些都是猜测。我从来没有做过和你以前一样的事,但其他的都没有道理。
也尝试选择一个新的CustomerStatus:
CustomerStatus = x.CustomerStatus.OrderByDescending(o => o.Date).Select(s => new CustomerStatus
{
x.Id,
x.Status,
x.Date,
x.CustomerId,
x.Customer,
x.StatusNavigation
})此时您可以删除Include/ThenInclude,因为选择这些关系的操作将导致连接。
发布于 2019-10-04 21:42:16
阅读后,从两个来源,(来源1)和(来源2)。我认为,如果您在Include之后使用Include,则会发生这样的情况。它无视Include,即使您在select中使用Include查询数据。因此,要解决这个问题,请在调用.AsEnumerable()之前使用select。
query = _context.Customers
.Include(x => x.CustomerStatus)
.ThenInclude(x => x.StatusNavigation)
.AsEnumerable()
.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);https://stackoverflow.com/questions/58102597
复制相似问题