Ошибка API критериев NHibernate с созданием псевдонима и набора прогнозов

Мне поручено создать список данных участников с помощью API NHibernate Criteria. Мне нужно включить разбиение на страницы и фильтрацию на основе флажков в пользовательском интерфейсе. Это немного усложняет то, что я не просто получаю данные из одной сущности, но эта сущность имеет отношение HasMany к другим сущностям.

У меня сейчас ошибка:

Error executing multi Criteria: 
[SELECT DISTINCT TOP 1000 this_MemberID as y0_ 
 FROM _Members
 Left Outer Join _SubMemberTerms ON _SubMemberTerms.MemberID = this_.MemberID
 Left Outer Join _MemberTerms ON _MemberTerms.MemberID = this_.MemberID
 Left Outer Join _ScriptOption ON _ScriptOption.ID = _MemberTerms.ScriptOpID
 WHERE _MagazineID = 100
 AND 
    (_ScriptOption.MagID IN (1234,5678,9101,.....) 
        OR _ScriptOption.MemberID IS NULL
        OR _ScriptOption.Active = 0)
 AND
    (_SubMemberTerms._ScriptOpID IN (1234,5678,9101,.....)
        OR _SubMemberTerms.ID IS NULL);]

Внутреннее исключение: значение \ "5554302 \" не относится к типу \ "MyBusiness.MemberInfo \" и не может использоваться в этой общей коллекции. Имя параметра: значение.

Прямо сейчас я просто смотрю на ID участника, потому что я закомментировал все остальные прогнозы в моем списке прогнозов. В противном случае в ошибке было бы указано "Значение \" System.object [] \ "...

Мой код критериев:

var filteredList = CurrentSession.CreateCriteria<MemberInfo>("this_")
                   .SetProjection(Projections.Distinct(Projections.ProjectionList()
                   .Add(Projections.Alias(Projections.Property("ManagedMemberID"), "MemberID"))))
                   .Add(Restrictions.Eq("_MagazineID", (int)magID))
                   .CreateAlias("MemTermsList", "_MemberTerms", NHibernate.SqlCommand.JoinType.LeftOuterJoin)
                   .CreateAlias("_MemberTerms.ScriptOpInfo", "_ScriptOption", NHibernate.SqlCommand.JoinType.LeftOuterJoin)
                   .CreateAlias("SubTermsList", "_SubMemberTerms", NHibernate.SqlCommand.JoinType.LeftOuterJoin)
                   .SetFirstResult(startposition)
                   .SetMaxResults(1000);

У меня также есть Criteria, предназначенный для подсчета всего запроса, а не только возвращенного 1k. Он такой же, как Criteria, который я сделал для filteredList.

//code for how I'm adding in the MagID's and ScriptOpId's
Disjunction magDisjunction = new Disjunction();
Disjunction subTermsDijunction = new Disjunction();
if(TheCheckBoxThatAppliesIsChecked)
{
    magDisjunction.Add(Restrictions.In("_ScriptOption.MagID", (List<int>)selectedMags))
                  .Add(Restrictions.IsNull("_MemberTerms.MemberID"))
                  .Add(Restrictions.Eq("_MemberTerms.Active", false));

    filteredList.Add(magDisjunction);
}
if(TheOtherCheckBoxThatAppliesIsChecked)
{
    subTermsDisjunction.Add(Restrictions.In("_SubMemberTerms.SciptOpID", (List<int>)selectedScriptOp))
                  .Add(Restrictions.IsNull("_SubMemberTerms.SubMemberTermsID"));

    filteredList.Add(subTermsDisjunction);
}

var finishedList = filteredList.Future<MemberInfo>().ToList<MemberInfo>();
var count = listCount.FutureValue<int>().Value;

РЕДАКТИРОВАТЬ: У меня была опечатка в моих прогнозах. Алиас переключил форму "MemberID" на "ManagedMemberID".


person CSMHowitzer    schedule 23.02.2012    source источник
comment
stackoverflow.com/questions/318157/ Это сообщение, которое привело меня к тому, что я бросил свой список свойств в список критериев   -  person CSMHowitzer    schedule 23.02.2012


Ответы (1)


запрос filteredlist имеет

.SetProjection(Projections.Distinct(Projections.ProjectionList().Add(Projections.Alias(Projections.Property("MemberID"), "MemberID"))))

который совпадает с

.SetProjection(Projections.Distinct(Projections.Property("MemberID")))

это означает, что запрос filteredlist возвращает MemberID, но

var finishedList = filteredList.Future<MemberInfo>().ToList<MemberInfo>();

заявляет, что filteredList возвращает MemberInfo, что приводит к ошибке

ЗАМЕТКА:

Future() - это просто нет, поскольку вы немедленно звоните ToList(). измените это на

var finishedList = filteredList.Future<int>();
var count = listCount.FutureValue<int>();

чтобы получить пакетную обработку запросов

Обновление:

Я бы избавился от проекции и использовал

int count = CriteriaUtil.Clone(query).SetProjection(Projections.RowCount()).FutureValue<int>();
var results = query.Future<MemberInfo>();


View.MemberCount = count.Value;  // executes both sql together here
foreach (MemberInfo result in results)
{
    // do something with the result
}
person Firo    schedule 23.02.2012
comment
круто, я попробую. Я собираюсь уйти с работы, так что не займусь этим до завтра. Также Projection.Alias ​​(Projection.Property (MemberID), MemberID) на самом деле является Projection.Alias ​​(Projection.Property (ManagedMemberID), MemberID). Это была всего лишь опечатка, извините, и теперь я отредактирую сообщение перед тем, как уйти. - person CSMHowitzer; 23.02.2012
comment
Я сделал то, что вы упомянули, избавился от моего .ToList ‹MemberInfo›, и теперь я могу обойти эту строку кода. Мне просто нужно выяснить, как получить эти данные сейчас. - person CSMHowitzer; 24.02.2012