仅从集合中获取第一个元素

本文关键字:第一个 元素 获取 集合 | 更新日期: 2023-09-27 18:35:52

我正在尝试检索存储为列表的财产的所有记录。此实体具有照片集合,此集合最多可以填充 5 张图像。

为了减少加载时间,我想检索属性列表,并且每个属性内部仅从集合中获取第一张照片。由于此查询

List<Domain.Property> data = session.Query<Domain.Property>()
                       .Fetch(x => x.Photos.First())
                       .ToList();

给我这个错误。提取请求必须是简单的成员访问表达式;'[100002]' 是一个 SubQueryExpression。参数名称:相关对象选择器。

所以我用

List<Domain.Property> data = session.Query<Domain.Property>()
                       .ToList();

我尝试在列表和foreach循环中检索属性以访问每个属性并在nhib中加载照片对象。

 var a = PropertyViewModel.FromDomainModel(data, session);
 public static List<PropertyViewModel> FromDomainModel(IList<Property> x, ISession session)
        {
            List<PropertyViewModel> dataVm = new List<PropertyViewModel>();
            foreach (Property p in x)
            {
                Photo firstPhoto = session.Get<Photo>(p.Photos[0].Id);
                dataVm.Add(new PropertyViewModel(p, firstPhoto));
            }
            return dataVm;
        }
public PropertyViewModel(Property x, Photo y)
        {
            Id = x.Id;
            ...
            Photo = new Photo();
            Photo = y;
        }

这种方法即使看起来不错(至少对我来说:)),它也根据 nhib 加载。 剖析器 65 个实体(其中照片标识符为 46 个加载,属性标识符为 19 个标识符)。(它应该为每个属性加载 19 个属性标识和 19 个照片标识第一个图像)。

我应该在这里做错什么?

我不熟悉投影,所以它应该是最后的解决方案。

谢谢

仅从集合中获取第一个元素

我认为如果没有投影(.Select())调用,您将无法做到这一点。

使用foreach时加载如此多照片的原因是,您正在访问带有p.Photos[0]的照片收藏夹,这会触发NHibernate对该收藏集的延迟加载。所有照片都从数据库加载,然后使用索引器[0]选择第一个照片。

即使您使用的是 LINQ 的 .First() 方法而不是索引器,也可能在此处触发延迟加载,因为您不是在 IQueryable 实例上调用它,而是在动态代理对象上调用它。

如果你在 Domain.Photo 和 Domain.Property 之间有关系,那么对照片进行查询并预先加载 Property 会更容易,就像这样(我还没有测试这是否编译,但它应该给你一个大致的想法):

var subQuery = QueryOver.Of<Domain.Property>().Select(x => x.Min(y => y.Photos));
List<Domain.Photo> data = session.QueryOver<Domain.Photo>()
     .WhereRestrictionOn(x => x.Id).IsIn(subQuery)
     .Fetch(x => x.Property).Eager
     .List();