首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Linq -按in包括的顺序

Linq -按in包括的顺序
EN

Stack Overflow用户
提问于 2019-09-25 16:12:17
回答 3查看 1.6K关注 0票数 4

在我的情况下,需要为Include对象执行OrderBy。到目前为止,我就是这样做的。

代码语言:javascript
运行
复制
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表。

我甚至试过这个,但都帮不了我。

代码语言:javascript
运行
复制
_context.Customers
    .Include(x => x.CustomerStatus.OrderByDescending(y => y.Date).FirstOrDefault())
    .ThenInclude(x => x.StatusNavigation).FirstOrDefault(x => x.Id == 3);

我做错什么了,请指点我

甚至我也试过这样做

代码语言:javascript
运行
复制
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次访问,并在内存中过滤结果。首先从客户状态选择所有数据,然后从状态选择,然后从客户筛选内存中的所有数据。有没有其他有效的方法来做到这一点?

这就是我按实体类准备的方法。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-09-30 07:58:49

正如@Chris所提到的,一旦您在select中执行,新客户,您将创建一个新模型。您正在丢弃由EntityFramework构建的模型。我的建议是:

代码语言:javascript
运行
复制
query = _context.Customers
    .Include(x => x.CustomerStatus)
    .ThenInclude(x => x.StatusNavigation);

就像这样,您将有一个IQueryable对象,除非您从它中进行选择,否则不会执行它:

代码语言:javascript
运行
复制
var customer3 = query.FirstOrDefault(x=>x.Id==3)

它返回客户和互连表(CustomerStatus和StatusNavigation)。然后,您可以创建所需的对象:

代码语言:javascript
运行
复制
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 {.}),它可能表明数据库模式没有很好地定义以满足应用程序的需要,因此可能需要重构。

票数 5
EN

Stack Overflow用户

发布于 2019-09-25 16:49:39

我认为正在发生的事情是,您实际上正在重写IncludeThenIncludeInclude显式地加载导航属性.然而,您正在做的一些事情可能会妨碍这一点。

首先,选择一个新的Customer。光是这一点就足以打破Include的逻辑。其次,您正在重写CustomerStatus集合中的内容。理想情况下,应该通过Include自动加载它,但通过修改它使其只具有第一个实体,实际上是在丢弃Include的效果。(选择关系就足以导致发出联接,而无需显式调用Include)。第三,ThenInclude是以Include为基础的,因此覆盖性很可能也会丢弃ThenIncude

所有这些都是猜测。我从来没有做过和你以前一样的事,但其他的都没有道理。

也尝试选择一个新的CustomerStatus

代码语言:javascript
运行
复制
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,因为选择这些关系的操作将导致连接。

票数 5
EN

Stack Overflow用户

发布于 2019-10-04 21:42:16

阅读后,从两个来源,(来源1)(来源2)。我认为,如果您在Include之后使用Include,则会发生这样的情况。它无视Include,即使您在select中使用Include查询数据。因此,要解决这个问题,请在调用.AsEnumerable()之前使用select

代码语言:javascript
运行
复制
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);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58102597

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档