如何执行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
对象。
对于开发人员来说,这听起来不像是一个新问题,但是我还没有找到任何讨论如何做到这一点的参考资料。
更新:
我添加了一个订单。
如果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....但这是特例