如何执行find()并在找到的实体之前和之后返回实体?

本文关键字:实体 之后 返回 执行 何执行 find | 更新日期: 2023-09-27 18:08:16

我试图执行一个查询,在那里我得到返回一个对象在我的SQL表中的记录之一。在本例中,它是一个DbImageModel对象(请参阅下面的代码)。下面的代码可以很好地根据查询条件返回单个实体:

s.ImageTag == imageTag

但我需要找到一种方法来返回之前的实体之后的当前发现的实体。或者至少是之前的之后的imageTag值。这可能吗?

我的代码如下:
using (UsersDbContext ctx = new UsersDbContext())
{
    try
    {
        DbImageModel image = ctx.Images.Include(i => i.Application)
              .OrderBy(c => c.ImageId)
              .FirstOrDefault(s => s.ImageTag == imageTag);
        // Do something with image
    }
    catch (Exception ex)
    {
        throw new NotImplementedException();  // For debugging
    }
}

我还应该提到,我的数据库关系被设置为多个DbImageModel对象到单个DbApplicationModel。一个DbUserModel对象对应多个DbApplicationModel对象。

对于开发人员来说,这听起来不像是一个新问题,但是我还没有找到任何讨论如何做到这一点的参考资料。

更新:

我添加了一个订单。

如何执行find()并在找到的实体之前和之后返回实体?

如果ImageId始终是增量的,则可以在发现的ImageId的设置范围内选择项目:

    DbImageModel images = 
        from i in ctx.Images.Include(i => i.Application)
        let match = ctx.Images.FirstOrDefault(s => s.ImageTag == imageTag)
        where i.ImageId < match.ImageId + 1 &&
            i.ImageId > match.ImageId - 1
        order by i.ImageId
        select i;

然而,我想你不能总是假设这是事实。例如,如果您允许删除图像,则会出现空白。很可能,您最好的选择是使用多次往返。首先使用您提供的代码找到图像,然后:

DbImageModel imageAfter = ctx.Images.Include(i => i.Application)
    .OrderBy(i => i.ImageId)
    .FirstOrDefault(i => i.ImageId > image.ImageId);
DbImageModel imageBefore = ctx.Images.Include(i => i.Application)
    .OrderByDescending(i => i.ImageId)
    .FirstOrDefault(i => i.ImageId < image.ImageId);

您可能会提出某种复杂的查询,在一次往返中生成所有这些,但其复杂性最终可能使其花费的时间比这三次往返的总和还要长。

我要在这里回答我自己的问题。因为,YES,有一种方法-至少对于多个查询-我想避免,但是,哦,好吧。

using (UsersDbContext ctx = new UsersDbContext())
{
    try
    {
        DbImageModel image = ctx.Images.Include(i => i.Application)
              .OrderBy(c => c.ImageId)
              .FirstOrDefault(s => s.ImageTag == imageTag);
        DbImageModel previousImage = ctx.Images.OrderBy(c => c.ImageId)
              .FirstOrDefault(s => s.ImageId < image.ImageId);
        DbImageModel nextImage = ctx.Images.OrderBy(c => c.ImageId)
              .FirstOrDefault(s => s.ImageId > image.ImageId);
        // Do something with image(s)
    }
    catch (Exception ex)
    {
        throw new NotImplementedException();  // For debugging
    }
}

注意:ImageId是SQL自动递增的记录id

让我们忽略这样一个事实,即在以未定义的顺序返回数据的查询中,before/after没有任何意义(就像任何SQL一样-服务器可以以任何它想要的顺序返回数据,除非您定义了顺序,而这个示例没有)。

不,不可能。

你基本上必须实现你自己的扩展方法来做到这一点。这是一个非常罕见的请求,他们没有将其嵌入到标准SQL中。

您必须枚举所有数据(首先可以在数据库中使用TOP 1 -但这意味着您只能获得一行到客户端),这将对性能产生影响。

如果你有之前/之后的东西,如ID -然后你可以使用一个连接,并得到一个包加入ID -1加入ID +1....但这是特例