3

我正在尝试检索存储为列表的属性实体的所有记录。这个实体有照片的集合,这个集合最多可以填充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 加载。profiler 65 个实体(其中 Photo 标识符是 46 个 load 和 Property 19 个标识符)。 (它应该为每个属性加载 19 个属性标识和 19 个照片标识。第一个图像)。

我应该在这里做错什么?

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

谢谢

4

2 回答 2

1

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

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

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

于 2012-05-31T00:52:30.660 回答
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();
于 2012-05-31T14:38:18.743 回答