【问题标题】:Performance Issue with NHibernate QueryNHibernate 查询的性能问题
【发布时间】:2014-09-11 21:05:11
【问题描述】:

我目前在使用 NHibernate 编写的以下查询时遇到性能问题。我正在尝试将我查询的数据转换为 DTO。有了这个复杂的结构,我不能使用 QueryOver 来转换实体。另一方面,Linq 提供程序非常有用,但每 30 个子项加载和转换约 6000 个实体需要约 10 秒。它创建一个带有左外连接的 SQL 查询。还有其他方法可以用更好的方法编写此查询吗?

var Entities = session.Query<crmEntity>()
         .Where(x => x.EntityType.ID == EntityType)
         .Select(entity => new EntityDTO()
         {
             ID = entity.ID,
             EntityType = entity.EntityType.ID,
             InstanceID = entity.Instance.ID,
             Values = entity.Values.Select(
               value => new CustomFieldValueDTO()
             {
                 ID = value.ID,
                 FieldID = value.Field.ID,
                 Value = value.Value
             }).ToList<CustomFieldValueDTO>()
         }).ToList();

【问题讨论】:

  • 您确定要获取Values 吗?在发布的代码中看起来不是这样。
  • 是的,它正在热切地工作。 HasMany(x => x.Values) .KeyColumn("Entity") .Cascade.AllDeleteOrphan() .Fetch.Select() .BatchSize(1000);
  • 另外,当我在 ".Select(..." 之前添加 Fetch(x=>x.Values) 时,大约需要 20 秒。
  • 一个建议是将您的 Values 类型从 List 更改为 IEnumerable 并删除 ToList() 调用。这将加快您的转换速度。
  • 谢谢,我会试试的。是否可以在 NH 的 QueryOver 或 Criteria API 中编写相同的查询?

标签: performance linq nhibernate dto


【解决方案1】:

这是我的解决方案。如果还有其他更好的方法,我完全愿意接受:

  session.CreateQuery(@"select vals.ID, 
                               vals.Field.ID,
                               vals.Value,
                               ent.ID 
               from crmEntity ent inner join ent.Values vals
               with vals.Value IS NOT NULL
               where ent.EntityType.ID=:eID and ent.Instance.ID=:instanceID order by ent.ID")
  .SetGuid("instanceID", InstanceID)
  .SetGuid("eID", EntityType)
  .SetResultTransformer(new EntityListTransformer()).Future<ReadOnlyEntityDTO>();

这是我的自定义结果转换器,用于获得与我的 linq 查询相同的层次结构

public class EntityListTransformer : IResultTransformer
    {
        private List<ReadOnlyEntityDTO> list;
        private ReadOnlyEntityDTO lastEntity;
        private Guid instanceID;

        public EntityListTransformer()
        {
            list = new List<ReadOnlyEntityDTO>();
            lastEntity = new ReadOnlyEntityDTO();
        }

        public System.Collections.IList TransformList(System.Collections.IList collection)
        {
            return list;
        }

        public object TransformTuple(object[] tuple, string[] aliases)
        {
            string ValueID = tuple[0].ToString();
            string FieldID = tuple[1].ToString();
            string Value = (string)tuple[2];
            string EntityID = tuple[3].ToString();


            if (lastEntity.ID != EntityID)
            {
                if (lastEntity.ID != null)
                {
                    list.Add(lastEntity);
                }


                lastEntity = new ReadOnlyEntityDTO()
                {
                    ID = EntityID
                };
            }

            lastEntity.Values.Add(new ReadOnlyCustomFieldValueDTO()
            {
                FieldID = FieldID,
                ID = ValueID,
                Value = Value
            });


            return tuple;
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-05
    • 1970-01-01
    • 2013-02-18
    • 2013-01-20
    相关资源
    最近更新 更多