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

3

我想检索存储为列表的所有Property实体记录。 该实体具有照片集合,该集合最多可填充5张图片。

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

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

我得到了这个错误。一个fetch请求必须是一个简单的成员访问表达式;'[100002]'是一个SubQueryExpression而不是。参数名称:relatedObjectSelector。

所以我使用

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

我试图在列表和foreach循环中检索属性,以便访问每个属性并将照片对象加载到nhib.session中,就像这样

 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. profiler加载了65个实体(其中照片标识符有46个,属性标识符有19个)。 (它应该首先加载19个属性标识符和19个照片标识符,每个属性的第一张图片)。

我在这里做错了什么?

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

谢谢


你能试试 session.Query<Domain.Property>().Fetch(x => x.Photos).First().ToList() 吗? - GregRos
#Greg Ros那样做不行,无论如何还是谢谢。 - BobRock
2个回答

1

我认为你不能在没有投影(.Select())调用的情况下完成这个操作。

当使用foreach时,你访问了一个Photos集合,其中p.Photos[0]触发了NHibernate的延迟加载机制,导致加载了所有的照片,然后使用索引器[0]选择第一张照片。

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


没有什么了不起的...向第一位问候 :) - Miroslav Popovic

0
如果Domain.Photo和Domain.Property之间有关联,那么在查询Photo并预加载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();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接