copy_to object property field to main document field - c#

I have my models as:
class Entity
{
public List<Prop> PropList { get; set; }
public List<string> Props { get; set; }
// others
}
class Prop
{
public string Name { get; set; }
public List<string> Tags { get; set; }
}
I want to copy all Prop's.Names in PropList to List<string> Props so that they are include in _source.
Is that possible with elasticsearch copy_to?
I tried the following, which didn't work,
.Mappings(des => des
.AutoMap()
.Properties(propsDes => propsDes
.Object<Prop>(objDes => objDes
.Name(propDes => propDes.PropList)
.AutoMap()
.Properties(objPropsDes => objPropsDes
.Text(s => s
.Name(e => e.Name)
.CopyTo(fieldDes => fieldDes.Field("props"))
)
)
)
)
)

Related

How apply condition for multiple properties

Hello I am trying to use AutoMapper for a mapping. Let's imagine I have a domain class like that and a DTO one with the exact same structure.
public class Address
{
public int State { get; set; }
public string StateCode { get; set; }
public int City { get; set; }
public string Street { get; set; }
public string ZipCode { get; set; }
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Phone { get; set; }
public Address Address { get; set; }
...
}
I want to construct a mapping that allows me only set the properties Phone and Address (and others, but for simplicity let's assume is only these two) conditionally depending on the value of the property age. Moreover, if the condition of the age property is met I want conditionally set the property StateCode only if the property State is not null. The logic is described below.
var personDto = new personDto();
personDto.Id = person.Id;
personDto.Name = person.Name;
personDto.Age = person.Age;
if(person.Age > 18)
{
personDto.Phone = person.Phone;
personDto.Address = new AddressDto();
personDto.Address.State = person.Address.State;
if (person.Address.State != null)
{
personDto.Address.StateCode = person.Address.StateCode;
}
personDto.Address.Street = person.Address.Street;
personDto.Address.ZipCode = person.Address.ZipCode;
}
I am trying to apply the same logic using Auto mapper, but I did not find in the documentation a way to do this.
CreateMap<Person, PersonDto>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Id))
.ForMember(d => d.Age , o => o.MapFrom(s => s.Age))
.ForMember(d => d.Name , o => o.MapFrom(s => s.Name ))
.ForMember(d => d.Phone , o =>
{
o.Condition(s => s.Age > 18); // I do not want repeat same condition for every property
o.MapFrom(s => s.Phone );
})
.ForMember(d => d.Address, o =>
{
o.Condition(s => s.Age > 18);
o.MapFrom(s => s.Address); // how can I nest the if condition of the State property here?
})
...
How can I apply the same nested logic here on Auto mapper? The whole point is how I can configure the mapping of several properties respecting the same condition and configure the nested condition as shown previously.

.Nest Fluent Dsl Aggregations

I am using Elasticsearch .Nest.
I need to create a search query that will return fileProperties objects but only of the latest version of each fileProperties.
Each FileId have many versions. So what I need is to do a groupBy FileId and get the whole document object with the Max version for each FileId.
This my class:
public class FileProperties
{
public string FileName { get; set; }
public string FileId { get; set; }
public long? Version { get; set; }
public string FileType { get; set; }
public Dictionary<string,string> DynamicProperties { get; set; }
}
and my code:
var searchResponse = client.Search<FileProperties>(s => s.AllIndices().Size(100)
.Query(q =>
q.Match(m => m
.Field(f => f.FileName)
.Query(fileId))
&& q.Match(m => m
.Field(f => f.Version)
.Query(version))).Aggregations(fstAgg => fstAgg
.Terms("file", f => f
.Field(z => z.FileId.Suffix("keyword"))
.ExecutionHint(TermsAggregationExecutionHint.GlobalOrdinals)
.Aggregations(sums => sums
.Max("version", son => son
.Field(f4 => f4.Version )
)
)
) ) );
But the results only show the key and the max value for that key.
what I want is the full document object if that is possible...
Any ideas?

Mappings : use CopyTo from a nested object to feed a parent property

I have these classes :
public class A
{
public string Name { get; set; }
public IEnumerable<B> Children { get; set; }
public IEnumerable<string> SearchField { get; set; }
}
public class B
{
public string Name { get; set; }
}
I work on an application that requires to copy into the property "SearchField" all the data that can be searched. I'm trying to copy in this field the value of the Name property of all the B children, but for the moment I didn't find a way to do that...
Any idea ? My current code :
map
.Properties(props => props
.Text(t => t.Name(n => n.SearchField))
.Text(t => t.Name(n => n.Name))
.Object<B>(c => c
.Name(n => n.Children)
.Properties(p => p
.Text(t => t.Name(b => b.Name)).CopyTo(a => ???????)
)
)
)

Include collection in Entity Framework Core

For example, I have those entities:
public class Book
{
[Key]
public string BookId { get; set; }
public List<BookPage> Pages { get; set; }
public string Text { get; set; }
}
public class BookPage
{
[Key]
public string BookPageId { get; set; }
public PageTitle PageTitle { get; set; }
public int Number { get; set; }
}
public class PageTitle
{
[Key]
public string PageTitleId { get; set; }
public string Title { get; set; }
}
How should I load all PageTitles, if I know only the BookId?
Here it is how I'm trying to do this:
using (var dbContext = new BookContext())
{
var bookPages = dbContext
.Book
.Include(x => x.Pages)
.ThenInclude(x => x.Select(y => y.PageTitle))
.SingleOrDefault(x => x.BookId == "some example id")
.Pages
.Select(x => x.PageTitle)
.ToList();
}
But the problem is, that it throws exception
ArgumentException: The properties expression 'x => {from Pages y
in x select [y].PageTitle}' is not valid. The expression should represent
a property access: 't => t.MyProperty'. When specifying multiple
properties use an anonymous type: 't => new { t.MyProperty1,
t.MyProperty2 }'. Parameter name: propertyAccessExpression
What's wrong, what exactly should I do?
Try accessing PageTitle directly in ThenInclude:
using (var dbContext = new BookContext())
{
var bookPages = dbContext
.Book
.Include(x => x.Pages)
.ThenInclude(y => y.PageTitle)
.SingleOrDefault(x => x.BookId == "some example id")
.Select(x => x.Pages)
.Select(x => x.PageTitle)
.ToList();
}

Automapper Project.To breaks db IQueryable

I have entities:
[Table("Representatives")]
public class Representative
{
[Column("RepID"), Key]
public int Id { get; set; }
[Column("MemID")]
public int MemberId { get; set; }
public virtual Member Member { get; set; }
}
[Table("Members")]
public class Member
{
[Column("MemID"), Key]
public int Id { get; set; }
[ForeignKey("MemberId")]
public virtual ICollection<Representative> Representatives { get; set; }
}
where Representatives relate to Member as many to one. I want to retrieve some representatives with their parent members and project it all to some view model. I've configured automapper like this:
Mapper.CreateMap<Representative, RepresentativeViewModel>()
.ForMember(m => m.RepId, a => a.MapFrom(x => x.Id))
.ForMember(m => m.MemberModel, a => a.MapFrom(x => x.Member));
Mapper.CreateMap<Member, MemberViewModel>()
.ForMember(m => m.MemId, a => a.MapFrom(x => x.Id))
.ForMember(m => m.OrganizationName, a => a.MapFrom(x => x.Name));
If I run this code:
var prj = ctx.Representatives.Where(r => r.Id == 1).Project().To<RepresentativeViewModel>();
then I get expression tree that contains func invocation (debugged):
...
.Lambda #Lambda2<System.Func`2[ConsoleApplication1.Representative,ConsoleApplication1.RepresentativeViewModel]>(ConsoleApplication1.Representative $var1)
{
.New ConsoleApplication1.RepresentativeViewModel(){
Name = $var1.Name,
RepId = $var1.Id,
MemberModel = .Invoke (.Lambda #Lambda3<System.Func`2[ConsoleApplication1.Member,ConsoleApplication1.MemberViewModel]>)($var1.Member)
}
}
.Lambda #Lambda3<System.Func`2[ConsoleApplication1.Member,ConsoleApplication1.MemberViewModel]>(ConsoleApplication1.Member $var2)
{
.New ConsoleApplication1.MemberViewModel(){
MemId = $var2.Id,
OrganizationName = $var2.Name
}
}
...
so for some reason builder invokes Func instead of calling Expression. Do you have ideas why it's so? How can I make my mapper build correct expression and SQL query?

Categories

Resources