Проблемы с производительностью с NHibernate Query
В настоящее время у меня проблема с производительностью следующего запроса, написанного в NHibernate. Я пытаюсь преобразовать данные, которые я запрашивал, в DTO. С этой сложной структурой я не могу использовать QueryOver для преобразования сущностей. С другой стороны, поставщик Linq очень полезен, но для загрузки и преобразования ~6000 сущностей с каждыми 30 дочерними элементами требуется ~ 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();
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;
}
}