We are trying to use QueryOver and projects. Basically it works fine. But we are currently struggling with a projection which should contain multiple items. The problem is that we have pallets which can contain pallet items. Pallet items are the base classes for various subclasses. We need to be able to projects only one property of each subclass MagazinePlaceLoadingOverviewData. Any ideas how we could achieve this?
Information: Magazine contains Levels, Levels contains Places, Places can have one Pallet assigned and a pallet can have multiple pallet items on it. Pallet items can be of various subtypes. We tried to get into the subtypes by implementing a visitor pattern on the pallet item but we can't even get the query below working.
MagazinePlaceLoadingEntity magazineLoadingAlias = null;
MagazinePlaceSettingsEntity magazinePlaceAlias = null;
MagazineLevelSettingsEntity magazineLevelAlias = null;
MagazineSettingsEntity magazineAlias = null;
MagazinePlaceLoadingOverviewData overviewAlias = null;
PalletEntity palletAlias = null;
PalletTypeSettingsEntity palletTypeAlias = null;
PalletItemEntity palletItemsAlias = null;
return session.QueryOver(() => magazineLoadingAlias)
.JoinAlias(x => x.Pallet, () => palletAlias)
.JoinAlias(() =开发者_StackOverflow> palletAlias.PalletType, () => palletTypeAlias)
.JoinQueryOver(x => x.Place, () => magazinePlaceAlias)
.JoinQueryOver(x => x.Level, () => magazineLevelAlias)
.JoinQueryOver(x => x.Magazine, () => magazineAlias)
.Where(x => x.Id == this.magazineId)
.Select(
Projections.Property(() => magazinePlaceAlias.Id).WithAlias(() => overviewAlias.MagazinePlaceId),
Projections.Property(() => magazineLoadingAlias.PalletInProgress).WithAlias(() => overviewAlias.PalletInProgress),
Projections.ProjectionList().Add(Projections.Property(() => palletAlias.PalletItems), () => overviewAlias.Items),
Projections.Property(() => palletTypeAlias.Classification).WithAlias(() => overviewAlias.PalletTypeClassification))
.TransformUsing(Transformers.AliasToBean<MagazinePlaceLoadingOverviewData>())
.List<MagazinePlaceLoadingOverviewData>();
This leads to the following exception
System.Data.SqlServerCe.SqlCeException: The column aliases must be unique. [ Name of duplicate alias = y2_ ]
at System.Data.SqlServerCe.SqlCeCommand.ProcessResults(Int32 hr)
at System.Data.SqlServerCe.SqlCeCommand.CompileQueryPlan()
at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand(CommandBehavior behavior, String method, ResultSetOptions options)
at System.Data.SqlServerCe.SqlCeCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
at NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd)
at NHibernate.Loader.Loader.GetResultSet(IDbCommand st, Boolean autoDiscoverTypes, Boolean callable, RowSelection selection, ISessionImplementor session)
at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters)
NHibernate.Exceptions.GenericADOException: could not execute query
[ SELECT magazinepl3_.Id as y0_, this_.PalletInProgress as y1_, palletalia1_.Id as y2_, pallettype2_.Classification as y2_ FROM "MagazinePlaceLoading" this_ inner join "Pallet" palletalia1_ on this_.PalletId=palletalia1_.Id inner join "PalletTypeSettings" pallettype2_ on palletalia1_.PalletTypeSettingsId=pallettype2_.Id inner join "MagazinePlaceSettings" magazinepl3_ on this_.MagazinePlaceSettingsId=magazinepl3_.Id inner join "MagazineLevelSettings" magazinele4_ on magazinepl3_.MagazineLevelSettingsId=magazinele4_.Id inner join "MagazineSettings" magazineal5_ on magazinele4_.MagazineSettingsId=magazineal5_.Id WHERE magazineal5_.Id = @p0 ]
Positional parameters: #0>cb9ff95a-58ca-4b2b-9aa6-9f6c008fc0b3
[SQL: SELECT magazinepl3_.Id as y0_, this_.PalletInProgress as y1_, palletalia1_.Id as y2_, pallettype2_.Classification as y2_ FROM "MagazinePlaceLoading" this_ inner join "Pallet" palletalia1_ on this_.PalletId=palletalia1_.Id inner join "PalletTypeSettings" pallettype2_ on palletalia1_.PalletTypeSettingsId=pallettype2_.Id inner join "MagazinePlaceSettings" magazinepl3_ on this_.MagazinePlaceSettingsId=magazinepl3_.Id inner join "MagazineLevelSettings" magazinele4_ on magazinepl3_.MagazineLevelSettingsId=magazinele4_.Id inner join "MagazineSettings" magazineal5_ on magazinele4_.MagazineSettingsId=magazineal5_.Id WHERE magazineal5_.Id = @p0]
at NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters)
at NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters)
at NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes)
at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results)
at NHibernate.Impl.CriteriaImpl.List(IList results)
at NHibernate.Impl.CriteriaImpl.List()
at NHibernate.Impl.CriteriaImpl.Subcriteria.List()
at NHibernate.Criterion.QueryOver`1.List()
at NHibernate.Criterion.QueryOver`1.NHibernate.IQueryOver<TRoot>.List<U>()
at .Domain.Queries.Magazines.GetLoadingOverviewByMagazineQuery.Find(ISession session) in GetLoadingOverviewByMagazineQuery.cs: line 41
at .Domain.Queries.QueryTestBase.Execute(IEnumerableQuery`1 query) in QueryTestBase.cs: line 39
at .Domain.Queries.Magazines.GetLoadingOverviewByMagazineQueryTest.Find_ShouldReturnOverviewData() in GetLoadingOverviewByMagazineQueryTest.cs: line 39
You can't do this:
Projections.ProjectionList().Add(Projections.Property(() => palletAlias.PalletItems), () => overviewAlias.Items),
AliasToBean
Transformer means you are flattening your results set. You can't have a list inside your MagazinePlaceLoadingOverviewData
.
You will need to get your list of items as a second query and join them together using Linq To Objects if you want them in that format.
精彩评论