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

时间:2012-05-30 21:14:41

标签: c# linq nhibernate linq-to-nhibernate

我正在尝试检索存储为List的所有Property权利记录。 这个实体有照片集,这个集合最多可以填充5张图片。

为了减少加载时间我想要检索属性列表,并且在每个属性中只有第一张照片来自集合。 自此查询

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

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

所以我用

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个实体(其中Photo标识符为46个加载,属性19标识符)。 (它应该加载19个属性标识和19个照片标识。每个属性的第一个图像)。

我该怎么办?

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

由于

2 个答案:

答案 0 :(得分:1)

如果没有投影(.Select())调用,我认为你不能这样做。

使用foreach时加载这么多照片的原因是因为您正在访问带有p.Photos[0]的Photos集合,该集合触发了NHibernate的Lazy Loading for the collection。所有照片都从数据库加载,然后将使用索引器[0]选择第一个。

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

答案 1 :(得分:0)

如果你在Domain.Photo和Domain.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();