NHibernate Criteria API 错误,创建别名和投影集合

发布于 2025-01-08 06:48:32 字数 2860 浏览 2 评论 0原文

我的任务是使用 NHibernate Criteria API 生成成员数据列表。我需要根据用户界面中的复选框合并分页和过滤。使这一点变得更复杂的是,我不仅从一个实体获取数据,而且该实体与其他实体具有 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,因为我评论了我的投影列表中的所有其他投影。否则错误会指出“The Value \”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 与我为 filteredList 所做的 Criteria 相同

//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”。

I'm tasked with generating a list of member data using the NHibernate Criteria API. I need to incorporate paging and filtering based on checkboxes in the UI. What makes this a bit more complex is that I'm not just fetching data from one entity, but this entity has a HasMany relationship to other entities.

I currently have an error:

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);]

The Inner exception is: The value \"5554302\" is not of type
\"MyBusiness.MemberInfo\" and cannot be used in this generic
collection. Parameter name: value.

Right now I'm just looking at the Member's ID because I commented every other projection in my projection list out. Otherwise the error would've stated "The Value \"System.object[]\"...

My Criteria Code:

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);

I also have a Criteria made for getting the count of the total query and not just the 1k returned. It's the same as the Criteria I made for 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;

EDIT:
I had a typo in my projections.Alias, switched form "MemberID", to "ManagedMemberID".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

兰花执着 2025-01-15 06:48:32

查询 filteredlist has

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

which 与 which 相同

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

,这意味着查询 filteredlist 返回 MemberID

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

声明 filteredList 返回 MemberInfo这会导致错误

注意:

Future() 只是一个noop,因为您立即调用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
}

query filteredlist has

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

which is the same as

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

which means that the query filteredlist returns MemberID but

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

states that filteredList returns MemberInfo which results in the error

NOTE:

the Future() is just a noop since you are calling ToList() immediatly. change it to

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

to get query batching

Update:

I would get rid of the Projection and use

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文