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

时间:2014-06-12 15:11:38

标签: c# sql entity-framework

我正在尝试执行查询,在该查询中,我返回了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的{​​{1}}个对象。并且单个DbApplicationModel对象有许多DbApplicationModel个对象。

对于开发人员而言,这听起来不应该是一个新问题,但我找不到任何讨论这种方法的参考文献。

更新

我添加了一个订单。我的问题仍然适用。

3 个答案:

答案 0 :(得分:2)

我将在这里回答我自己的问题。因为,,有一种方法 - 至少有多个查询 - 我想避免这种方式,但很好。

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。

答案 1 :(得分:2)

如果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);

你有可能在一次往返中提出某种复杂的查询来产生所有这些,但它的复杂性最终可能会比这三次往返组合花费更长的时间。 / p>

答案 2 :(得分:-2)

让我们忽略这样一个事实:在查询之前/之后没有意义taht以未定义的顺序返回数据(正如任何SQL所做的那样 - 服务器dcan以任何顺序返回数据,除非你定义一个顺序,例如没有)。

不,没办法。

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

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

如果您之前/之后喜欢ID - 那么您可以使用连接并获得捆绑加入ID为-1的捆绑加入ID为+1的那个....但这是一个特殊情况。