Как мне вернуть строго типизированную коллекцию, которая запрашивает несколько сущностей с помощью CastleR ActiveRecord? - PullRequest
0 голосов
/ 25 марта 2009

Я пытаюсь получить определенный набор данных, соединяя вместе 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] на вершину моего класса LatestThread. Когда я делаю это, ему нужен первичный ключ, и это просто неправильный маршрут.

Я также прочитал биты, которые ссылаются на атрибут Import, данный классам, которые не являются DTO. Во всех примерах объединяются только две сущности, а не 4, которые у меня есть. Нужно ли добавлять импорт ко всем 4? Или есть что сказать AR, что это только для чтения класс DTO? ИЛИ Я делаю все это неправильно, и есть действительно простой способ сделать то, что я пытаюсь сделать.

ТИА!

Ответы [ 2 ]

2 голосов
/ 25 марта 2009

Добавьте атрибут 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()

Источник: http://www.kenegozi.com/Blog/2006/10/08/projection-using-activerecords-importattribute-and-hqls-select-new-clause.aspx

1 голос
/ 25 марта 2009

Вы не можете запросить тип, который не сопоставлен (что делает атрибут [ActiveRecord]). AFAIK, вы не можете заставить NHibernate создать новый экземпляр произвольного объекта, подобного этому, через HQL (я исправлюсь, если кто-то знает иначе).

Лучше всего сделать проекционный запрос, а затем создать метод сопоставления возвращаемых кортежей с экземплярами вашего типа.

Мой ответ здесь показывает, как выполнить проекционный запрос и сопоставить его с анонимным типом; то, что вы хотите сделать, не сильно отличается. Затем вы можете поместить метод для этого в репозиторий для конкретного типа или метод расширения со строгим типом в общий репозиторий.

...