How do I map from a source property to the destination? - automapper-2

I swear I've done it before, but I can't seem to get it to work now. Basically I'm getting an EndUser containing a Site, and I want to map that Site to a SiteInfo object.
Here's my map configuration:
Mapper.CreateMap<Site, SiteInfo>()
.ForMember(dest => dest.SiteID, opt => opt.MapFrom( src => src.ID))
.ForMember(dest => dest.CompanyID, opt => opt.MapFrom(src => src.Company.ID));
Mapper.CreateMap<EndUser, SiteInfo>()
.ForMember( dest => dest, opt => opt.MapFrom(src => src.Site ));
So EndUser.Site should be able to map to SiteInfo. I can do this on the outside by just calling Mapper.Map<SiteInfo>(EndUser.Site). I think it's just cleaner syntax to map from the end user to the location info directly.
So how can I map directly from EndUser to SiteInfo? Basically this is the code I'd LIKE to write:
var user = mcp.Users.GetEndUser(userAddress.Address);
var siteInfo = Mapper.Map<SiteInfo>(user);
Currently I'm working around the issue by just mapping from EndUser.Site like this:
var user = GetEndUser(emailAddress);
var siteInfo = user == null
? null as SiteInfo
: Mapper.Map<SiteInfo>(user.Site);

Do you want to map Location to SiteInfo or LocationInfo? What is the dest property you're mapping to in your EndUser -> SiteInfo mapping? Does SiteInfo contain a combination of both Location and EndUser properties?
Without that info I'm only guessing, but are you trying to do something like this?
var rc = Mapper.Map<SiteInfo>(endUser);
rc = Mapper.Map(endUser.Location, rc);
UPDATE
So if I understand correctly, you're after a mapping like this?
Mapper.CreateMap<EndUser, SiteInfo>()
.ForMember(dest => dest.SiteID, opt => opt.MapFrom( src => src.Site.ID))
.ForMember(dest => dest.CompanyID, opt => opt.MapFrom(src => src.Site.Company.ID));

Related

Laravel 8 uploading two images seperately. added same image names in database

This is the controller code:
$player1QID = time().'.'.$request->player1_Id->extension();
$images1= $request->player1_Id->move(public_path('images'), $player1QID);
$player2QID = time().'.'.$request->player2_Id->extension();
$images2= $request->player2_Id->move(public_path('images'), $player2QID);
///this is adding to database:
$registeredusers = Registrations::create([
'tournament_id' => $request->input('tournament_id'),
'player1_name' => $request->input('player1_name'),
'player1_email' => $request->input('player1_email'),
'player1_Id' => $player1QID,
'player1_gender' => $request->player1_gender,
'player1_phone' => $request->input('player1_phone'),
'player2_name' => $request->input('player2_name'),
'player2_email' => $request->input('player2_email'),
'player2_Id' => $player2QID,
'player2_gender' => $request->player2_gender,
'player2_phone' => $request->input('player2_phone'),
'category' => $request->category,
'status' => $request->input('status'),
]);
This is in view blade:
Upload image1
Upload image2
Really appreciate if someone can help
you should first look at your inspection in Chrome, Firefox or whatever you are using, and check what your request contains, I mean if you are sending the images in separate names like:
...
player1_Id:
player2_Id:
...
i think, of course is sending like that because you are receiving it on your controller. Then try save it with datetime at end of name like:
public function obtainImage(Request $request){
$image1=request('player1_Id');
$this->manageImage($image1);
$image2=request('player2_Id');
$this->manageImage($image2);
}
public function manageImage($image){
$fileImageNameExtencion=$image->getClientOriginalName();
$fileName=pathInfo($fileImageNameExtencion, PATHINFO_FILENAME);
$fileExtencion=$image->getClientOriginalExtension();
$newFileName=$fileName."_".time().".".$fileExtencion;
$saveAs=$image->storeAs('public/images',$newFileName);
return $newFileName;
}
where $ newFileName is what you need to save to your database
otherwise you can do a dd ($ player1QID. '-'. $ player2QID) before saving to database and comparing names

Elasticsearch Autocomplete Issues

I am trying to create an Autocompletion using Elasticsearch.net, but i keep getting an Invalid response.
But cant figure out why?
My Request looks like this
var descriptor = new SearchDescriptor<EmployeeDocument>()
.Index("employees").Type("employee").From(page - 1).Size(pageSize)
.Suggest(
s => s.Completion(
"my-completion-suggest",
c => c
.Field(f1 => f1.Description)
.Field(f1 => f1.empfirstname)
.Contexts(
queriesDescriptor => queriesDescriptor.Context(
"query-descriptor",
queryDescriptor => queryDescriptor.Prefix(true).Context(query)))));
var response3 = await this.client.SearchAsync<EmployeeDocument>(descriptor);
the error i am getting is
Invalid NEST response built from a unsuccessful low level call on POST: /employees/employee/_search
Audit trail of this API call:
- [1] BadResponse: Node: http://192.168.2.29:9200/ Took: 00:00:00.3543244
ServerError: ServerError: 400Type: search_phase_execution_exception Reason: "all shards failed"
This is how i am calling the method
var results1 = await service.SearchAsync("brenda", page, pageSize);
var results8 = await service.SearchAsync("something else", page, pageSize);
My model is also very straightforward. I left out some properties
[ElasticsearchType(Name = "employee")]
public class EmployeeDocument
{
//[Text(Name = "pkempid")]
public long pkempid { get; set; }
//[Text(Name = "empfirstname")]
public string empfirstname { get; set; }
}
Description and empfirstname need to be mapped as completion field data types. The CompletionField type in NEST can be used for the property type, which will be mapped as a completion data type through automapping.
Additionally, a completion suggester can only specify one field, so chaining multiple calls to .Field() will not work as expected (the last call will be the field used). You can however specify multiple suggesters in one request targeting different fields. It's more usual though, rather than having multiple completion fields in a mapping, to specify multiple input values to a single completion field.
The use case for the completion suggester is to provide fast "search as you type" autocompletion functionality, trading off the power of more complex analysis chains that can be performed with text field data types.
Ok, so I figured out how to do autocomplete, I ended up using Edge NGram Tokenizer First thing I needed to do was setup my indexes with the correct filters.
var response = this.client.CreateIndex(
ElasticConfig.IndexName,
index => index.Mappings(
ms => ms.Map<EmployeeDocument>(
m => m.Properties(
p => p
.Text(t => t.Name(n => n.EmpFirstName).Analyzer("auto-complete").Fields(ff => ff.Keyword(k => k.Name("keyword"))))
.Text(t => t.Name(n => n.pkEmpID).Analyzer("auto-complete-id").Fields(ff => ff.Keyword(k => k.Name("keyword"))))
.Text(t => t.Name(n => n.Description).Analyzer("auto-complete").Fields(ff => ff.Keyword(k => k.Name("keyword")))))))
.Settings(f => f.Analysis(
analysis => analysis
.Analyzers(
analyzers => analyzers
.Custom("auto-complete", a => a.Tokenizer("standard").Filters("lowercase", "auto-complete-filter"))
.Custom("auto-complete-id", a => a.Tokenizer("standard").Filters("lowercase", "auto-complete-id-filter")))
.TokenFilters(tokenFilter => tokenFilter
.EdgeNGram("auto-complete-filter", t => t.MinGram(3).MaxGram(5))
.EdgeNGram("auto-complete-id-filter", t => t.MinGram(1).MaxGram(5))))));
Then for the actual search
var response = await this.client.SearchAsync<EmployeeDocument>(
x => x.Index("default-index").Type("employee").From(page - 1).Size(pageSize)
.Query(q => q
.MultiMatch(m => m
.Query(query)
.Fields(f => f
.Field(_ => _.EmpFirstName)
.Field(_ => _.pkEmpID)
.Field(_ => _.Description))))
.Highlight(
h => h.PreTags("<mark>").PostTags("</mark>").Fields(
f => f.Field(p => p.EmpFirstName),
f => f.Field(p => p.pkEmpID),
f => f.Field(p => p.Description))));

NHibernate JoinQueryOver returns all subtype entries

I know there are many similar topics but I couldn't find the answer I am searching for.
I have Message with list of Receivers. I am trying to get all messages with state new and receivers of type A. I get all messages having corresponding receivers but with all of their receivers. I only want to get the receivers I am interested in.
Here is what I am trying to use:
var messages = session.QueryOver<MessageDTO>()
.Where(message => message.State == MessageState.New)
.JoinQueryOver<MessageReceiverDTO>(message => message.MessageReceivers)
.Where(receiver => receiver.Type == ReceiverType.A)
.TransformUsing(Transformers.DistinctRootEntity)
.List();
//.Where(message => message.MessageReceivers.Count > 0)
//.ToList();
Would be great to have help with that. I also tried using Select for getting message and receiver out of the query but that didn't work neither.
Try QueryOver with alias:
MessageDTO messageAlias = null;
MessageReceiverDTO receiverAlias = null;
var query =
session.QueryOver<MessageDTO>(() => messageAlias)
.JoinAlias(() => messageAlias.Receivers, () => receiverAlias)
.Where(() => messageAlias.State == MessageState.New)
.And(() => receiverAlias.Type == ReceiverType.A);
I think Transformers.AliasToEntityMap might be useful here. Basically it transforms each row in your resulting query to an IDictionary with keys corresponding to alias names and values corresponding to entities. For example:
MessageDTO message = null;
MessageReceiverDTO receiver = null;
var messages = session.QueryOver<MessageDTO>(() => messageAlias)
.Where(message => message.State == MessageState.New)
.JoinQueryOver<MessageReceiverDTO>(message => message.MessageReceivers, () => receiver)
.Where(receiver => receiver.Type == ReceiverType.A)
.TransformUsing(Transformers.AliasToEntityMap)
.List<IDictionary>();
MessageDTO firstMessage = (MessageDTO)messages[0]["message"];
MessageReceiverDTO firstReceiver = (MessageReceiverDTO)messages[0]["receiver"];

NHibernate Fetch when querying for single object

I'm trying to optimize an NHibernate query:
var profile = dc.Profiles.FirstOrDefault(p => p.IdProfile == idProfile);
I would like it to load a collection of Rights. I did this:
var profile = dc.Profiles.Fetch(x => x.Rights).FirstOrDefault(p => p.IdProfile == idProfile);
The results were totally different from what I expected - instead of getting single Profile with rights I got single profile with single right!
How can I fix it?
You can use like this
var profile = dc.Profiles.Where(p => p.IdProfile == idProfile).Select(x => x.Rights);

Is this the right way of using ThenFetch() to load multiple collections?

I'm trying to load all the collections eagerly, using NHibernate 3 alpha 1. I'm wondering if this the right way of using ThenFetch()?
Properties with plural names are collections. The others are just a single object.
IQueryable<T> milestoneInstances = Db.Find<T, IQueryable<T>>(db =>
from mi in db
where mi.RunDate == runDate
select mi).Fetch(mi => mi.Milestone)
.ThenFetch(m => m.PrimaryOwners)
.Fetch(mi => mi.Milestone)
.ThenFetch(m => m.SecondaryOwners)
.Fetch(mi => mi.Milestone)
.ThenFetch(m => m.Predecessors)
.Fetch(mi => mi.Milestone)
.ThenFetch(m => m.Function)
.Fetch(mi => mi.Milestone)
.ThenFetchMany(m => m.Jobs)
.ThenFetch(j => j.Source)
;
I thought of asking this in the NHibernate forums but unfortunately access to google groups is forbidden from where I am. I know Fabio is here, so maybe the guys from the NHibernate team can shed some light on this?
Thanks
Apparently, there's no "right" way to use ThenFetch in such a case. Your example works fine but SQL produced contains many joins to Milestone, which isn't that right.
Using IQueryOver instead of IQueryable allows you to use complex syntax in Fetch:
Fetch(p => p.B)
Fetch(p => p.B.C) // if B is not a collection ... or
Fetch(p => p.B[0].C) // if B is a collection ... or
Fetch(p => p.B.First().C) // if B is an IEnumerable (using .First() extension method)
So in your case it would be:
query // = session.QueryOver<X>()
.Fetch(mi => mi.Milestone).Eager
.Fetch(mi => mi.Milestone.PrimaryOwners).Eager
.Fetch(mi => mi.Milestone.SecondaryOwners).Eager
.Fetch(mi => mi.Milestone.Predecessors).Eager
.Fetch(mi => mi.Milestone.Function).Eager
.Fetch(mi => mi.Milestone.Jobs).Eager
.Fetch(mi => mi.Milestone.Jobs.First().Source).Eager
The one thing you are missing is that you should use FetchMany() and ThenFetchMany() is the child property is a collection.
IQueryable<T> milestoneInstances = Db.Find<T, IQueryable<T>>(db =>
from mi in db
where mi.RunDate == runDate
select mi);
var fetch = milestoneInstances.Fetch(f => f.Milestone);
fetch.ThenFetch(f => f.PrimaryOwners);
fetch.ThenFetch(f => f.SecondaryOwners);
//...
As leora said, make sure when fetching children collections that you use
FetchMany()
ThenFetchMany()
A new Fetch, should pick up from the root, but this does not always happen. Sometimes you need to create them as separate queries or use Criteria Futures to batch up a multiple fetch.