how multiple map in automapper - c#

I recently met with an automapper. I have a question, how i can map multiple objects from my repostiory in one DTO.
public QuestionProfile()
{
CreateMap<Question, GrammarQuestionDTO>()
.ForMember(g => g.Question, q => q.MapFrom(source => source.Text)).ReverseMap();
CreateMap<List<GrammarQuestionDTO>, TestDTO>()
.ForMember(t => t.GrammarQuestion, g => g.MapFrom(source => source)).ReverseMap();
CreateMap<Question, AuditionQuestionDTO>()
.ForMember(a => a.Question, q => q.MapFrom(source => source.Text))
.ForMember(a => a.Url, q => q.MapFrom(source => source.AudioFile.Url)).ReverseMap();
CreateMap<List<AuditionQuestionDTO>, TestDTO>()
.ForMember(t => t.AuditionQuestion, a => a.MapFrom(source => source)).ReverseMap();
}
how can I map all these 4 objects?
public async Task<TestDTO> GenerateTest(LevelType level)
{
var grammarQuestions = await _questionRepository.GetGrammarQuestionAsync(level);
var auditionQuestions = await _questionRepository.GetAuditionQuestionAsync(level);
var essayTopic = await _questionRepository.GetEssayTopicAsync(level);
var speakingTopic = await _questionRepository.GetSpeakingTopicAsync(level);
var test = _mapper.Map<TestDTO>(grammarQuestions);
test = _mapper.Map(test, auditionQuestions); //there will be a conversion error
return _mapper.Map<TestDTO>(grammarQuestions);
}

You need to map it without list, just map it one to one and AutoMapper will handle the collections:
CreateMap<AuditionQuestionDTO, TestDTO>()
.ForMember(t => t.AuditionQuestion,
a => a.MapFrom(source => source.<PropertyName>)).ReverseMap();
And then on the map you should:
test = _mapper.Map<List<AuditionQuestionDTO>>(test, auditionQuestions);

Related

.Net Core 3 EF - Order Included Array

I am trying to return the newest result of Status from n array of statuses, but I have no idea how to implement this on an include.
public async Task<IEnumerable<Ticket>> GetTickets()
{
var tickets = await _context.Tickets
.Include(c => c.Client)
.Include(r => r.Region)
.Include(rl => rl.RouteLink)
.Include(e => e.Engineer)
.Include(p => p.Priority)
.Include(s => s.Statuses.).ThenInclude(s => s.Status)
.Include(tcb => tcb.TicketCreatedBy)
.Include(t => t.Team)
.ToListAsync();
return tickets;
}
Something like this would help.
var tickets = await _context.Tickets
.Include(c => c.Client)
.Include(r => r.Region)
.Include(rl => rl.RouteLink)
.Include(e => e.Engineer)
.Include(p => p.Priority)
.Include(s => s.Statuses.).ThenInclude(s => s.Status)
.Include(tcb => tcb.TicketCreatedBy)
.Include(t => t.Team)
.Select(x => new TicketDto
{
...
Statuses = x.Statuses.OrderByDescending(o => o.DateProperty).Take(1)
...
})
.ToListAsync();
but then you won't need Include directives because of the usage of Select

NHibernate QueryOver with SelectList

I have multiple queries against one table. As not all columns/properties are needed I specify the columns with the help of select list. Take the following method as example. This method is working
public IEnumerable<ResultDto> GetEntityAsDto(eStatusBinderProduktion fromState, eStatusBinderProduktion toState)
{
EntityClass entityAlias = null;
ResultDto resultAlias = null;
var query = Session.QueryOver<EntityClass>(() => entityAlias)
.Where(() => entityAlias.ProduktionStatus >= (byte)fromState)
.And(() => entityAlias.ProduktionStatus <= (byte)toState);
query.SelectList(list => list
.Select(() => entityAlias.PrimaryID).WithAlias(() => resultAlias.PrimaryID)
.Select(() => entityAlias.SecondaryID).WithAlias(() => resultAlias.SecondaryID)
);
return query.TransformUsing(Transformers.AliasToBean<ResultDto>())
.List<ResultDto>();
}
As I need to define the SelectList in multiple methods, I tried to to move the SelectList into a separate method.
The following code is not working, NHibernate throws the exception
NHibernate.QueryException: 'could not resolve property: entity.PrimaryID of: MyProjectNamespace.DAL.Interfaces.Entities.EntityClass'
"
public IEnumerable<ResultDto> GetEntityAsDto(eStatusBinderProduktion fromState, eStatusBinderProduktion toState)
{
EntityClass entityAlias = null;
ResultDto resultAlias = null;
var query = Session.QueryOver<EntityClass>(() => entityAlias)
.Where(() => entityAlias.ProduktionStatus >= (byte)fromState)
.And(() => entityAlias.ProduktionStatus <= (byte)toState);
MapPropertiesOfEntityToResult(entityAlias, resultAlias, query);
return query.TransformUsing(Transformers.AliasToBean<ResultDto>())
.List<ResultDto>();
}
private void MapPropertiesOfEntityToResult(EntityClass entity, ResultDto resultAlias, IQueryOver<EntityClass, EntityClass> query)
{
query.SelectList(list => list
.Select(() => entity.PrimaryID).WithAlias(() => resultAlias.PrimaryID)
.Select(() => entity.SecondaryID).WithAlias(() => resultAlias.SecondaryID)
);
}
Additional information:
- The mappings are correct
- table is filled with test data
We do not need alias for filling SelectList. We can profit from the Type parameters coming with IQueryOver<TRoot,TSubType>:
//private void MapPropertiesOfEntityToResult(EntityClass entity
// , ResultDto resultAlias, IQueryOver<EntityClass, EntityClass> query)
private void MapPropertiesOfEntityToResult( // no need for entity
ResultDto resultAlias, IQueryOver<EntityClass, EntityClass> query)
{
query.SelectList(list => list
//.Select(() => entity.PrimaryID).WithAlias(() => resultAlias.PrimaryID)
//.Select(() => entity.SecondaryID).WithAlias(() => resultAlias.SecondaryID)
.Select(entity => entity.PrimaryID).WithAlias(() => resultAlias.PrimaryID)
.Select(entity => entity.SecondaryID).WithAlias(() => resultAlias.SecondaryID)
);
}
The entity is now a parameter of the passed Function and its type is coming from IQueryOver definition

Nhibernate Group By and Alias To Bean

I have been struggling to get an old query translated to Nhibernate.
We are upgrading an old project from Nhibernate 2 to the latest version.
I am using the QueryOver syntax since Linq wasn't an option because of the complexity of the queries (advice of a colleague).
I want to query the DB (Oracle) to get some results which have to be grouped.
As result I need a grouped collection of my DTO. I also noticed that nhibernate has trouble translating to a DTO with complex properties (nested DTO's)
To fix this I found this topic. This works great but I am not a fan of the magic strings...
I will add some code snippets of how my monster query is looking at this moment.
Problem is I can't seem to figure out how to add a group by without breaking everything else. So I would want to group on a property but still have the DTO in my results. Something like:
ILookup<int,IEnumerable<NieuwePrintopdrachtenInfo>>
Any help would be welcome.
Sorry the variables and classes are in Dutch -_-
SYNUITGAANDEBRIEF uitgaandebrief = null;
SYNAANVRAAG joinedAanvraag = null;
SYNDOSSIER joinedDossier = null;
SYNVERBRUIKSADRES joinedVerbruiksAdres = null;
SYNEAN joinedEan = null;
SYNCTENERGIETYPE joinedEnergieType = null;
SYNBRIEFBESTEMMELINGEN joinedBriefBestemmeling = null;
SYNCTBRIEFTYPE joinedBriefType = null;
SYNCTBRIEFSTATUS joinedBriefStatus = null;
SYNCONTACTPERSOON joinedContactpersoon = null;
SYNCTCONTACTPERSOONTYPE joinedBestemmelingType = null;
SYNCTVERZENDMODUSTYPE joinedVerzendModus = null;
SYNCTCONTACTPERSOONTYPE joinedContactpersoonType = null;
SYNCTTAAL joinedContactpersoonTaal = null;
SYNTOEWIJZVERBRUIKVERANT joinedVerbruiksVerantw = null;
SYNCTPROFIELGROEP joinedProfielGroep = null;
var baseQuery = SessionHandler.CurrentSession.QueryOver(() => uitgaandebrief)
.JoinAlias(() => uitgaandebrief.AANVRAAGCollection, () => joinedAanvraag)
.JoinAlias(() => joinedAanvraag.DOSSIER, () => joinedDossier)
.JoinAlias(() => joinedDossier.VERBRUIKSADRES, () => joinedVerbruiksAdres)
.JoinAlias(() => joinedAanvraag.EAN, () => joinedEan)
.JoinAlias(() => joinedEan.CtEnergietype, () => joinedEnergieType)
.JoinAlias(() => uitgaandebrief.BRIEFBESTEMMELINGENCollection, () => joinedBriefBestemmeling)
.JoinAlias(() => uitgaandebrief.CtBriefType, () => joinedBriefType)
.JoinAlias(() => uitgaandebrief.CtBriefStatus, () => joinedBriefStatus)
.JoinAlias(() => joinedBriefBestemmeling.CONTACTPERSOONCollection, () => joinedContactpersoon, JoinType.LeftOuterJoin)
.JoinAlias(() => joinedBriefBestemmeling.CtContactPersoonType, () => joinedBestemmelingType, JoinType.LeftOuterJoin)
.JoinAlias(() => joinedBriefBestemmeling.CtVerzendModus, () => joinedVerzendModus, JoinType.LeftOuterJoin)
.JoinAlias(() => joinedContactpersoon.CtContactpersoonType, () => joinedContactpersoonType, JoinType.LeftOuterJoin)
.JoinAlias(() => joinedContactpersoon.CtTaal, () => joinedContactpersoonTaal, JoinType.LeftOuterJoin)
.JoinAlias(() => joinedContactpersoon.TOEWIJZVERBRUIKVERANTCollection, () => joinedVerbruiksVerantw, JoinType.LeftOuterJoin)
.JoinAlias(() => joinedContactpersoon.CtProfielGroep, () => joinedProfielGroep, JoinType.LeftOuterJoin);
This is only the beginning. Here comes the part to filter the results (when needed).
if (briefType.HasValue)
{
baseQuery.Where(() => uitgaandebrief.BriefType == briefType.Value);
}
if (verzendModus.HasValue)
{
baseQuery.Where(() => joinedBriefBestemmeling.VerzendModus == verzendModus.Value);
}
if (!string.IsNullOrEmpty(binnenland) && binnenland.Trim() != "-1")
{
baseQuery.Where(() => joinedBriefBestemmeling.BinnenLand == binnenland.ToBoolean());
}
Then I got the part to select the stuff I need and translate it into the DTO (NieuwePrintopdrachtenInfo).
NieuwePrintopdrachtenInfo nieuwePrintopdrachtInfo = null;
baseQuery.SelectList(list => list
.Select(() => uitgaandebrief.UitgaandebriefId).WithAlias(() => nieuwePrintopdrachtInfo.UitgaandeBriefId)
.Select(() => uitgaandebrief.DatumInplanning).WithAlias(() => nieuwePrintopdrachtInfo.InplanningsDatum)
.Select(() => uitgaandebrief.ErrorReden).WithAlias(() => nieuwePrintopdrachtInfo.Probleem)
.Select(() => uitgaandebrief.ErrorNr).WithAlias(() => nieuwePrintopdrachtInfo.ErrorNummer)
.Select(() => uitgaandebrief.DatumCreatie).WithAlias(() => nieuwePrintopdrachtInfo.CreatieDatumBrief)
.Select(() => uitgaandebrief.DatumUpdate).WithAlias(() => nieuwePrintopdrachtInfo.DatumLaatsteWijzigingBrief)
.Select(() => uitgaandebrief.UserCreatie).WithAlias(() => nieuwePrintopdrachtInfo.BrieUserCreatie)
.Select(() => uitgaandebrief.UserUpdate).WithAlias(() => nieuwePrintopdrachtInfo.BriefUserUpdate)
.Select(() => uitgaandebrief.DatumAnnulatieElektriciteit).WithAlias(() => nieuwePrintopdrachtInfo.DatumElektriciteitGeannuleerd)
.Select(() => uitgaandebrief.DatumAnnulatieGas).WithAlias(() => nieuwePrintopdrachtInfo.DatumGasGeannuleerd)
.Select(() => joinedDossier.DossierId).WithAlias(() => nieuwePrintopdrachtInfo.DossierId)
.Select(() => joinedDossier.DossierNr).WithAlias(() => nieuwePrintopdrachtInfo.DossierNr)
.Select(() => joinedEnergieType.Omschrijving).WithAlias(() => nieuwePrintopdrachtInfo.EnergieTypeBrief)
.Select(() => joinedBriefType.Omschrijving).WithAlias(() => nieuwePrintopdrachtInfo.TypeBrief)
.Select(() => joinedVerzendModus.Omschrijving).WithAlias(() => nieuwePrintopdrachtInfo.VerzendModus)
.Select(() => joinedVerzendModus.Omschrijving).WithAlias(() => nieuwePrintopdrachtInfo.BestemmelingVerzendModus)
.Select(() => joinedBriefBestemmeling.BriefBestemmelingenId).WithAlias(() => nieuwePrintopdrachtInfo.BestemmelingId)
.Select(() => joinedBestemmelingType.Omschrijving).WithAlias(() => nieuwePrintopdrachtInfo.BestemmelingContactpersoonType)
.Select(() => joinedBriefBestemmeling.BestemmelingElektriciteit).WithAlias(() => nieuwePrintopdrachtInfo.BestemmelingElek)
.Select(() => joinedBriefBestemmeling.BestemmelingGas).WithAlias(() => nieuwePrintopdrachtInfo.BestemmelingGas)
.Select(() => joinedBriefBestemmeling.BinnenLand).WithAlias(() => nieuwePrintopdrachtInfo.BestemmelingBinnenLand)
.Select(() => joinedVerbruiksAdres.Land).WithAlias(() => nieuwePrintopdrachtInfo.LandVerbuiksadres)
.Select(Projections.Property(() => joinedContactpersoon.ContactpersoonId).As("BestemmelingContactPersoon.ContactPersoonId"))
.Select(Projections.Property(() => joinedContactpersoonType.Omschrijving).As("BestemmelingContactPersoon.TypeContactPersoon"))
.Select(Projections.Property(() => joinedContactpersoon.VoorNaam).As("BestemmelingContactPersoon.VoorNaam"))
.Select(Projections.Property(() => joinedContactpersoon.Naam).As("BestemmelingContactPersoon.Naam"))
.Select(Projections.Property(() => joinedContactpersoon.Straat).As("BestemmelingContactPersoon.Straat"))
.Select(Projections.Property(() => joinedContactpersoon.HuisNr).As("BestemmelingContactPersoon.HuisNummer"))
.Select(Projections.Property(() => joinedContactpersoon.BusNr).As("BestemmelingContactPersoon.BusNummer"))
.Select(Projections.Property(() => joinedContactpersoon.Gemeente).As("BestemmelingContactPersoon.Gemeente"))
.Select(Projections.Property(() => joinedContactpersoon.PostCode).As("BestemmelingContactPersoon.PostCode"))
.Select(Projections.Property(() => joinedContactpersoon.Appartement).As("BestemmelingContactPersoon.Appartement"))
.Select(Projections.Property(() => joinedContactpersoon.Verdieping).As("BestemmelingContactPersoon.Verdieping"))
.Select(Projections.Property(() => joinedContactpersoon.Telefoon1).As("BestemmelingContactPersoon.Telefoon1"))
.Select(Projections.Property(() => joinedContactpersoon.Telefoon2).As("BestemmelingContactPersoon.Telefoon2"))
.Select(Projections.Property(() => joinedContactpersoon.FAXNr).As("BestemmelingContactPersoon.Fax"))
.Select(Projections.Property(() => joinedContactpersoon.Email).As("BestemmelingContactPersoon.Email"))
.Select(Projections.Property(() => joinedContactpersoon.DatumCreatie).As("BestemmelingContactPersoon.DatumCreatie"))
.Select(Projections.Property(() => joinedContactpersoon.UserCreatie).As("BestemmelingContactPersoon.UserCreatie"))
.Select(Projections.Property(() => joinedContactpersoon.DatumUpdate).As("BestemmelingContactPersoon.DatumUpdate"))
.Select(Projections.Property(() => joinedContactpersoon.UserUpdate).As("BestemmelingContactPersoon.UserUpdate"))
.Select(Projections.Property(() => joinedContactpersoon.AdresBijTeWerken).As("BestemmelingContactPersoon.IsAdresBijTeWerken"))
.Select(Projections.Property(() => joinedContactpersoon.Titel).As("BestemmelingContactPersoon.Titel"))
.Select(Projections.Property(() => joinedContactpersoon.NietBesteldeBrief).As("BestemmelingContactPersoon.NietBesteldeBrief"))
.Select(Projections.Property(() => joinedContactpersoon.Land).As("BestemmelingContactPersoon.Land"))
.Select(Projections.Property(() => joinedContactpersoon.ContactpersoonAlsAanbrengerGebruikt).As("BestemmelingContactPersoon.ContactPersoonIdAlsAanbrenger"))
.Select(Projections.Property(() => joinedContactpersoon.ContactpersoonIsBetrokken).As("BestemmelingContactPersoon.ContactPersoonIsBetrokken"))
.Select(Projections.Property(() => joinedContactpersoon.NietAfgehaaldeBrief).As("BestemmelingContactPersoon.NietAfgehaaldeBrief"))
.Select(Projections.Property(() => joinedContactpersoonTaal.Omschrijving).As("BestemmelingContactPersoon.Taal"))
.Select(Projections.Property(() => joinedProfielGroep.Omschrijving).As("BestemmelingContactPersoon.IngegevenDoor"))
.Select(Projections.Property(() => joinedEan.Energietype).As("BestemmelingContactPersoon.EnergieType"))
.Select(Projections.Property(() => joinedVerbruiksVerantw.ToewijzigingVerbruiksVerantwoordelijkeId).As("BestemmelingContactPersoon.VerbruiksVerantwoordelijkeId")));
Yeah I know it is a mess. Now that you made it this far, you'll be happy to know we are almost there. This is the code I use to return the results (It is generic and uses the DeepTransform which I found here)
protected IEnumerable<TR> GetDeepTransformedPagedList<T, TR>(IQueryOver<T, T> query) where TR : class
{
PagingSettings.Count = query.Clone().Select(Projections.CountDistinct(PagingSettings.PropertyNameToCountOn)).FutureValue<int>().Value;
query = query.TransformUsing(new DeepTransformer<TR>());
if (PagingSettings.Enabled)
{
var pagedQuery = query.Skip(GetPagingStartRowIndex()).Take(PagingSettings.PageSize);
return pagedQuery.List<TR>();
}
return query.List<TR>();
}
EDIT
After the helpful post of Radim Köhler I found out that a group by won't help me with my problem. That's why I'll explain the real problem.
In code the previous query is build and extended with a Skip & Take for paging purpose. In my situation I get 50 results when executing the query.
These 50 results contain duplicates and need to be grouped by UitgaandeBriefId.
That's why the original developers wrote this code that is executed once the results are back from the DB.
ILookup<int, IEnumerable<NieuwePrintopdrachtenInfo>> groupedbrieven =
(from tbInfo in brieven
group tbInfo by tbInfo.UitgaandeBriefId into g
let UitgaandeBriefId = g.Key
let Group = g as IEnumerable<NieuwePrintopdrachtenInfo>
select new { UitgaandeBriefId, Group })
.ToLookup(result => result.UitgaandeBriefId, result => result.Group);
This code still works but results in getting only 32 results. This causes my pages to never contain 50 results. The original developer used server side paging instead of doing it on the DB so he never got this problem (performance wise this was a huge problem). That's why I refactored it so it would execute a lot faster, but this results in not getting exectly 50 results.
I guess I'll need to add a distinct then but I have no clue how I get this to work in NHibernate since I am used to work with EntityFramework.
In general, if we want to change our projection to be using GROUP BY, we have to change all "SELECT" parts to be either part of GROUP BY or SUM, MIN ...
We can do it with this kind of syntax
// firstly
// the original part from the question above
baseQuery.SelectList(list => list
...
.Select(() => joinedBriefBestemmeling.BinnenLand)
.WithAlias(() => nieuwePrintopdrachtInfo.BestemmelingBinnenLand)
.Select(() => joinedVerbruiksAdres.Land)
.WithAlias(() => nieuwePrintopdrachtInfo.LandVerbuiksadres)
.Select(Projections.Property(() => joinedContactpersoon.ContactpersoonId)
.As("BestemmelingContactPersoon.ContactPersoonId"))
.Select(Projections.Property(() => joinedContactpersoonType.Omschrijving)
.As("BestemmelingContactPersoon.TypeContactPersoon"))
...
// changed, to use GROUP BY
baseQuery.SelectList(list => list
...
.SelectGroup(() => joinedBriefBestemmeling.BinnenLand)
.WithAlias(() => nieuwePrintopdrachtInfo.BestemmelingBinnenLand)
.SelectGroup(() => joinedVerbruiksAdres.Land)
.WithAlias(() => nieuwePrintopdrachtInfo.LandVerbuiksadres)
.Select
(Projections.Alias
(Projections.GroupProperty
(Projections.Property(() => joinedContactpersoon.ContactpersoonId))
, "BestemmelingContactPersoon.ContactPersoonId"))
.Select
(Projections.Alias
(Projections.GroupProperty
(Projections.Property(() => joinedContactpersoonType.Omschrijving))
, "BestemmelingContactPersoon.TypeContactPersoon"))
...
So, now we have the GROUP BY (instead of just a SELECT) replacing the original code. But we can do more, we can introduce these (just a quick version) Extension methods (just a light version, really - but working)
public static class Extensions
{
public static NHibernate.Criterion.Lambda.QueryOverProjectionBuilder<T> GroupByProperty<T>(
this NHibernate.Criterion.Lambda.QueryOverProjectionBuilder<T> builder,
System.Linq.Expressions.Expression<Func<object>> propertyExpression,
System.Linq.Expressions.Expression<Func<object>> aliasExpression)
{
var alias = aliasExpression.ParseProperty();
var propertyProjection = Projections.Property(propertyExpression);
var groupProjection = Projections.GroupProperty(propertyProjection);
var withAliasProjection = Projections.Alias(groupProjection, alias);
builder.Select(withAliasProjection);
return builder;
}
public static string ParseProperty<TFunc>(this System.Linq.Expressions.Expression<TFunc> expression)
{
var body = expression.Body as System.Linq.Expressions.MemberExpression;
if (body.IsNull())
{
return null;
}
string propertyName = body.Member.Name;
ParseParentProperty(body.Expression as System.Linq.Expressions.MemberExpression, ref propertyName);
// change the alias.ReferenceName.PropertyName
// to just ReferenceName.PropertyName
var justAPropertyChain = propertyName.Substring(propertyName.IndexOf('.') + 1);
return justAPropertyChain;
}
static void ParseParentProperty(System.Linq.Expressions.MemberExpression expression, ref string propertyName)
{
if (expression.IsNull())
{
return;
}
// Parent.PropertyName
propertyName = expression.Member.Name + "." + propertyName;
ParseParentProperty(expression.Expression as System.Linq.Expressions.MemberExpression, ref propertyName);
}
}
And the above code could be made more readable and common, without any magic string
baseQuery.SelectList(list => list
...
.GroupByProperty(() => joinedBriefBestemmeling.BinnenLand)
,() => nieuwePrintopdrachtInfo.BestemmelingBinnenLand)
.GroupByProperty(() => joinedVerbruiksAdres.Land)
,() => nieuwePrintopdrachtInfo.LandVerbuiksadres)
.GroupByProperty(() => joinedContactpersoon.ContactpersoonId)
.() => nieuwePrintopdrachtInfo.BestemmelingContactPersoon.ContactPersoonId)
.GroupByProperty(() => joinedContactpersoonType.Omschrijving)
.() => nieuwePrintopdrachtInfo.BestemmelingContactPersoon.TypeContactPersoon)
...
NOTE IsNull() is also extension

NHibernate QueryOver and string.format

I am working with QueryOver in NHibernate and I want to customize one property of my projected DTO using the following syntax:
IEnumerable<PersonResponseMessage> persons =
session.QueryOver<PersonEntity>()
.SelectList(list => list
.Select(p => p.Active).WithAlias(() => dto.Active)
.Select(p => p.Alert).WithAlias(() => dto.Alert)
.Select(p => p.Comments).WithAlias(() => dto.Comments)
.Select(p => string.Format("{0}api/Person/{1}", uriHelper.Root, p.Id)).WithAlias(() => dto.DetailsUrl)
)
.TransformUsing(Transformers.AliasToBean<PersonResponseMessage>())
.List<PersonResponseMessage>();
Unfortunately NHibernate cannot do this and throws an exception saying that:
Variable P referenced from scope "" is not defined
There are in common two ways. Partially we can move that concat operation on the DB side, as documented here:
16.7. Projection Functions
In this case, we'll use the Projections.Concat:
.SelectList(list => list
.Select(p => p.Active).WithAlias(() => dto.Active)
.Select(p => p.Alert).WithAlias(() => dto.Alert)
.Select(p => p.Comments).WithAlias(() => dto.Comments)
// instead of this
//.Select(p => string.Format("{0}api/Person/{1}", uriHelper.Root, p.Id))
// .WithAlias(() => dto.DetailsUrl)
// use this
.Select(p => Projections.Concat(uriHelper.Root, Projections.Concat, p.Id))
.WithAlias(() => dto.DetailsUrl)
)
.TransformUsing(Transformers.AliasToBean<PersonResponseMessage>())
.List<PersonResponseMessage>();
But I would vote for ex-post processing on the Application tier, in C#:
.SelectList(list => list
.Select(p => p.Active).WithAlias(() => dto.Active)
.Select(p => p.Alert).WithAlias(() => dto.Alert)
.Select(p => p.Comments).WithAlias(() => dto.Comments)
// just the ID
.Select(p => p.Id).WithAlias(() => dto.Id)
)
.TransformUsing(Transformers.AliasToBean<PersonResponseMessage>())
.List<PersonResponseMessage>()
// do the concat here, once the data are transformed and in memory
.Select(result =>
{
result.DetailsUrl = string.Format("{0}api/Person/{1}", uriHelper.Root, p.Id)
return result;
});

Joins in nhibernate

I am using blow code for join in nhibernate, which is working fine. But i don't wants to use .List on both queries before join, i wants to use .List after join. I don't know nhibernate too much.. please provide me help that what i should make changes in below funciton to first join the data and then apply .List over it.
public IEnumerable<PGrp> GetSol()
{
_pGrpR = null;
_pGrp = null;
QueryOver<Phy, Phy> activePhyQuery = GetDataQuery();
var phyGrpR = _session.QueryOver(() => _pGrpR)
.Where(
Subqueries.WhereProperty<PGrpR>(p => _pGrpR.PhyId).In(
activePhyQuery))
.List<PGrpR>();
IList<PGrp> pGrps = _session.QueryOver(() => _pGrp)
.Where(x => !x.AC)
.List<PGrp>();
var newPGrps = pGrps
.Join(
pGrpR,
p => p.Id,
x => x.PGrpId,
(p, x) => p
).Distinct().OrderBy(x => x.Name);
return newPGrps;
}
Thanks
PGrpR pGrpR = null;
IList<PGrp> pGrps = _session.QueryOver(() => _pGrp)
.Where(x => !x.AC)
.JoinAlias(pgrps => pgrps.pGrpR, () => pGrpR) // Set real property name
.OrderBy(() => pGrpR.Name).Asc
.Select(Projections.Distinct(Projections.Property(() => pGrpR."PropertyForDistinct")))
.TransformUsing(Transformers.DistinctRootEntity)
.List<PGrp>();

Categories