Как мне вернуть строго типизированную коллекцию, которая запрашивает несколько объектов с помощью ActiveRecord от Castle?
-
22-08-2019 - |
Вопрос
Я пытаюсь получить определенный набор данных, объединяя для этого 4 разных объекта вместе.Что я сделал, так это настроил DTO, чтобы попытаться заставить это работать:
public class LatestThread
{
private readonly string comment;
private readonly DateTime posted;
private readonly string userName;
private readonly int reputation;
private readonly int threadId;
private readonly string topic;
private readonly int userId;
private readonly string avatar;
public LatestThread(string comment, DateTime posted, string userName, int reputation, int threadId, string topic, int userId, string avatar)
{
this.comment = comment;
this.avatar = avatar;
this.userId = userId;
this.topic = topic;
this.threadId = threadId;
this.reputation = reputation;
this.userName = userName;
this.posted = posted;
}
public string Comment
{
get { return comment; }
}
public DateTime Posted
{
get { return posted; }
}
public string UserName
{
get { return userName; }
}
public int Reputation
{
get { return reputation; }
}
public int ThreadId
{
get { return threadId; }
}
public string Topic
{
get { return topic; }
}
public int UserId
{
get { return userId; }
}
public string Avatar
{
get { return avatar; }
}
}
Теперь я подумал, что мог бы использовать SimpleQuery вот так:
string hql = string.Format("select new LatestThread(m.Comment, m.Posted, u.UserName, u.Reputation, t.Id, t.Topic, u.Id, u.Avatar) from Thread as t inner join Message as m on t.Id = m.ThreadId inner join User as u on u.Id = m.PostedById inner join Activity as a on a.Id = t.ActivityId where a.Lineage like '{0}%' order by t.LastPosted desc", activityLineage);
возвращает репозиторий.SimpleQuery(0, 10, hql);
Мой метод репозитория выглядит следующим образом:
public virtual IList<T> SimpleQuery<T>(int firstResult, int maxResults, string hql, params object[] parameters)
{
var query = new SimpleQuery<T>(hql, parameters);
query.SetQueryRange(firstResult, maxResults);
return query.Execute();
}
Теперь он просит меня поместить [ActiveRecord] в начало моего последнего класса Thread.Когда я делаю это, ему нужен первичный ключ, и это просто кажется неправильным маршрутом.
Я также прочитал биты, которые ссылаются на атрибут Import, присвоенный классам, которые не являются DTO.Однако во всех примерах это просто объединение двух объектов, а не 4, которые у меня есть.Нужно ли мне добавить Импорт ко всем 4?Или есть что-то, что подсказывает AR, что это класс DTO только для чтения?ИЛИ я все делаю неправильно, и есть действительно простой способ сделать то, что я пытаюсь сделать.
ТИА!
Решение
Добавьте атрибут Import в ваш новый класс Thread
[Import(typeof(LatestThread), "LatestThread")]
[ActiveRecord("Thread")]
public class Thread : ActiveRecordBase<Thread> { /* blah blah */ }
И затем происходит волшебство запроса :)
string hql = string.Format("select new LatestThread(m.Comment, m.Posted, u.UserName, u.Reputation, t.Id, t.Topic, u.Id, u.Avatar) from Thread as t inner join Message as m on t.Id = m.ThreadId inner join User as u on u.Id = m.PostedById inner join Activity as a on a.Id = t.ActivityId where a.Lineage like '{0}%' order by t.LastPosted desc", activityLineage);
SimpleQuery<LatestThread> query = new SimpleQuery<LatestThread>(typeof(Thread), hql );
LatestThread[] results = query.Execute()
Другие советы
Вы не можете запросить тип, который не сопоставлен (что и [ActiveRecord]
атрибут делает).AFAIK вы не можете заставить NHibernate создать новый экземпляр произвольного объекта, подобный этому, через HQL (я прошу исправить, если кто-то знает иначе).
Лучше всего выполнить проекционный запрос, а затем создать метод для сопоставления возвращаемых кортежей с экземплярами вашего типа.
Мой ответ здесь показывает, как выполнить проекционный запрос и сопоставить его с анонимным типом;то, что вы хотите сделать, не сильно отличается.Затем вы могли бы поместить метод для этого в репозиторий, зависящий от типа, или строго типизированный метод расширения в общий репозиторий.