How to map a mongodb entity to elasticsearch create index in c#? - c#

I am trying to create an index for my project to elasticsearch.
following are my classes
public class Asset
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public AssetComponent Component { get; set; }
public AssetSite Site { get; set; }
public AssetComposition AssetComposition { get; set; }
public string SerialNumber { get; set; }
public string WorkOrderNumber { get; set; }
public AssetFigure Figure {get;set;}
public string SkuNumber { get; set; }
public Status AssetStatus { get; set; }
public Status InspectionStatus { get; set; }
public BsonDocument UserDefinedAttributes { get; set; }
public TimeAndUserTrail Trail { get; set; }
[BsonIgnoreIfDefault]
public List<Identifier> Identifiers { get; set; } = new List<Identifier>();
[BsonIgnoreIfDefault]
public List<Document> Documents { get; set; } = new List<Document>();
public Status OrderStatus { get; set; }
}
public class AssetComponent
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Name { get; set; }
}
public class AssetSite
{
[BsonRepresentation(BsonType.ObjectId)]
public string LocationId { get; set; }
[BsonRepresentation(BsonType.ObjectId)]
public string SiteId { get; set; }
}
public class AssetComposition
{
public List<AssetComponentComposition> SubAssemblies { get; set; }
public List<AssetComponentComposition> Parts { get; set; }
public List<AssetComponentComposition> Accessories { get; set; }
}
public class AssetComponentComposition
{
public string Name { get; set; }
public string AssetType { get; set; }
public List<ObjectId> AssetIds { get; set; }
}
public class AssetFigure
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Name { get; set; }
}
public class Status
{
public string Id { get; set; }
public string Value { get; set; }
}
And in elasticsearch create index method
var createIndexResponse = client.CreateIndex(indexName, c => c
.Mappings(ms => ms
.Map<Asset>(m => m
.AutoMap<AssetComposition>()
.AutoMap<AssetComponent>()
.AutoMap<AssetSite>()
.AutoMap<AssetFigure>()
.AutoMap<BsonDocument>()
.AutoMap<TimeAndUserTrail>()
.AutoMap<Core.Entities.Status>()
.AutoMap(typeof(AssetComponentComposition))
.AutoMap(typeof(Identifier))
.AutoMap(typeof(Document))
.AutoMap(typeof(ObjectId))
)
)
);
When I run this, I am getting the following exception.
System.Reflection.AmbiguousMatchException: 'Ambiguous match found.'
I tried to resolve this using the following link from elasticsearch official document
https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/auto-map.html
But again I didn't resolved the issue. Please help.

The problem is occurring due to the 'BsonDocument' which has inbuilt properties which need to be map to the elastic search mapping environment. After adding those additional fields the issue resolved

Related

How Map Multiple related Entities to one DTO Object using AutoMapper EF Core

I have three related Entities in my blazor application Opportunity, AppUser and AssignedOpportunity, What I want to achieve is to map Opportunity and AppUser to a DTO Object ReturnAssignedOpportunityDTO which has similar fields as the entities, using AutoMapper, but am not sure how to do that, below are the entities
public partial class AssignedOpportunity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[ForeignKey("OpportunityID")]
public string OpportunityID { get; set; }
public string Status { get; set; }
public Opportunity opportunity { get; set; }
[ForeignKey("UserID")]
public string UserID { get; set; }
public AppUser User { get; set; }
}
The opportunity
public partial class Opportunity
{
public Opportunity()
{
AssignedOpportunities= new HashSet<AssignedOpportunity>();
}
[Key]
public string ID { get; set; }
public string OpportunityName { get; set; }
public string Description { get; set; }
public string CreatedBy { get; set; }
public DateTime DateCreated { get; set; }
public double EstimatedValue { get; set; }
public string EmployeeNeed { get; set; }
public double RealValue { get; set; }
public string Location { get; set; }
public string ReasonStatus { get; set; }
public string Status { get; set; }
public virtual ICollection<AssignedOpportunity> AssignedOpportunities { get; set; }
}
AppUser Class
public partial class AppUser : IdentityUser
{
public AppUser()
{
AssignedOpportunities = new HashSet<AssignedOpportunity>();
}
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string LGA { get; set; }
public string State { get; set; }
public virtual ICollection<AssignedOpportunity> AssignedOpportunities { get; set; }
}
Here's the DTO Object I want to map to.
public class ReturnOpportunitiesDTO
{
public int ID { get; set; }
public string OpportunityID { get; set; }
public string OpportunityName { get; set; }
public double EstimatedValue { get; set; }
public string EmployeeNeed { get; set; }
public double RealValue { get; set; }
public string Location { get; set; }
public string UserID { get; set; }
public string UserFullName { get; set; }
public string Status { get; set; }
}
Here is my query to fetch the records
var result = await _context.AssignedOpportunities.Include(o => o.opportunity).
ThenInclude(a => a.User).
Where(a=>a.UserID==UserID.ToString()).ToListAsync();
return result;
This is how i usually setup Map Profile
public AssignArtisanProfile()
{
CreateMap<AssignedOpportunity, ReturnOpportunities>();
}
But since I want to map multiple entities, how do I include the other entity
Your scenario is just another example of flattening a complex object. You have properties in child objects, which you want to bring to the ground level, while still leveraging AutoMapper mapping capabilities. If only you could reuse other maps from app user and opportunity when mapping from assigned opportunity to the DTO... Well, there is a method called IncludeMembers() (see the docs) that exists precisely for such case. It allows you to reuse the configuration in the existing maps for the child types:
config.CreateMap<AssignedOpportunity, ReturnOpportunitiesDTO>()
.IncludeMembers(source => source.opportunity, source => source.User);
config.CreateMap<Opportunity, ReturnOpportunitiesDTO>();
config.CreateMap<AppUser, ReturnOpportunitiesDTO>()
.ForMember(
dest => dest.UserFullName,
options => options.MapFrom(source =>
string.Join(
" ",
source.FirstName,
source.MiddleName,
source.LastName)));
Usage:
var mappedDtos = mapper.Map<List<ReturnOpportunitiesDTO>>(assignedOpportuniesFromDatabase);

E.F Core does not return all values When Include another table

public IEnumerable<Parties> GetAll()
{
return database.Parties;
}
Works very well and the output is:
But when I Include another table by foreignkey like this:
public IEnumerable<Parties> GetAll()
{
return database.Parties.Include(i=>i.User);
}
It does not work, it returns first value of the table and nothing else,the output is :
Users.cs :
public partial class Users
{
public Users()
{
Parties = new HashSet<Parties>();
PartyParticipants = new HashSet<PartyParticipants>();
}
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string Avatar { get; set; }
public string Biography { get; set; }
public string Password { get; set; }
public virtual ICollection<Parties> Parties { get; set; }
public virtual ICollection<PartyParticipants> PartyParticipants { get; set; }
}
Parties.cs :
public partial class Parties
{
public Parties()
{
Image = new HashSet<Image>();
PartyParticipants = new HashSet<PartyParticipants>();
}
public int Id { get; set; }
public string Name { get; set; }
public DateTime PartyDate { get; set; }
public DateTime CreatedDate { get; set; }
public int ParticipantCount { get; set; }
public int MaxParticipant { get; set; }
public string PartySplash { get; set; }
public string ShortDescription { get; set; }
public string Description { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public bool EntranceFree { get; set; }
public int? FreeParticipant { get; set; }
public int? FreeParticipantMax { get; set; }
public int UserId { get; set; }
public virtual Users User { get; set; }
public virtual ICollection<Image> Image { get; set; }
public virtual ICollection<PartyParticipants> PartyParticipants { get; set; }
}
As you can see on the 2nd picture it interrupts at first row of the table.
I have added this answer based on Vidmantas's comment. ReferenceLoopHandling should be ignored like this in startup.cs:
services.AddMvc()
.AddJsonOptions(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});

How to remove $ for json result?

I am trying to read a cell value from a simple google sheet
https://docs.google.com/spreadsheets/d/1opP1t_E9xfuLXBkhuyzo5j9k_xBNDx0XKb31JwLP1MM/edit?usp=sharing
then I published it and I get an API link that return JSON, check the following
https://spreadsheets.google.com/feeds/list/1opP1t_E9xfuLXBkhuyzo5j9k_xBNDx0XKb31JwLP1MM/1/public/values?alt=json
when I tried to generate C# classes from JSON using http://json2csharp.com/, I get
invalid_name and $ (which is not fine for csharp compiler)
public class Id
{
public string __invalid_name__$t { get; set; }
}
public class Updated
{
public DateTime __invalid_name__$t { get; set; }
}
public class Category
{
public string scheme { get; set; }
public string term { get; set; }
}
public class Title
{
public string type { get; set; }
public string __invalid_name__$t { get; set; }
}
public class Link
{
public string rel { get; set; }
public string type { get; set; }
public string href { get; set; }
}
public class Name
{
public string __invalid_name__$t { get; set; }
}
public class Email
{
public string __invalid_name__$t { get; set; }
}
public class Author
{
public Name name { get; set; }
public Email email { get; set; }
}
public class OpenSearchTotalResults
{
public string __invalid_name__$t { get; set; }
}
public class OpenSearchStartIndex
{
public string __invalid_name__$t { get; set; }
}
public class Id2
{
public string __invalid_name__$t { get; set; }
}
public class Updated2
{
public DateTime __invalid_name__$t { get; set; }
}
public class Category2
{
public string scheme { get; set; }
public string term { get; set; }
}
public class Title2
{
public string type { get; set; }
public string __invalid_name__$t { get; set; }
}
public class Content
{
public string type { get; set; }
public string __invalid_name__$t { get; set; }
}
public class Link2
{
public string rel { get; set; }
public string type { get; set; }
public string href { get; set; }
}
public class GsxName
{
public string __invalid_name__$t { get; set; }
}
public class GsxPhonenumber
{
public string __invalid_name__$t { get; set; }
}
public class Entry
{
public Id2 id { get; set; }
public Updated2 updated { get; set; }
public List<Category2> category { get; set; }
public Title2 title { get; set; }
public Content content { get; set; }
public List<Link2> link { get; set; }
public GsxName __invalid_name__gsx$name { get; set; }
public GsxPhonenumber __invalid_name__gsx$phonenumber { get; set; }
}
public class Feed
{
public string xmlns { get; set; }
public string __invalid_name__xmlns$openSearch { get; set; }
public string __invalid_name__xmlns$gsx { get; set; }
public Id id { get; set; }
public Updated updated { get; set; }
public List<Category> category { get; set; }
public Title title { get; set; }
public List<Link> link { get; set; }
public List<Author> author { get; set; }
public OpenSearchTotalResults __invalid_name__openSearch$totalResults { get; set; }
public OpenSearchStartIndex __invalid_name__openSearch$startIndex { get; set; }
public List<Entry> entry { get; set; }
}
public class RootObject
{
public string version { get; set; }
public string encoding { get; set; }
public Feed feed { get; set; }
}
I want to serialize and deserialize this class, also i want to remove $,what i need to do?
Obviously json2csharp converts each json object into a class and converts the key names into variable names literally. So whenever it finds a key name starting with $ it can't create a c# variable with this character and it precedes the variable name with a _invalid_name_. There is nothing wrong here.
You should tell why do you want to remove this invalid_name phrase from variable name? do you want to serialize and deserialize this class? If so you could use NewtonSoft Json library and define those fields with $ sign like this:
[JsonProperty(PropertyName = "$t")]
public string t { get; set; }
this will allow you to serialize/deserialize the json doc
same for gsx$name:
[JsonProperty(PropertyName = "gsx$name")]
public string gsxname { get; set; }

PHP error with multiple levels of key-value JSON pairs

I am using multiple levels of JSON data coming into php from a C# application, as in:
public class User_Group
{
public int ID_UserGroup { get; set; }
public string Name_UserGroup { get; set; }
public int UserID { get; set; }
}
public class User_Role
{
public int ID_User { get; set; }
public string Role_User { get; set; }
public string User_Role_Description { get; set; }
public List<User_Group> UserGroup { get; set; }
}
public class Stand_Orte
{
public int ID { get; set; }
public string Bezeichnung { get; set; }
public List<Modul> modul { get; set; }
}
public class Modul
{
public string ID { get; set; }
public string Seriennummer { get; set; }
public string Bezeichnung { get; set; }
public string StandortID { get; set; }
public List<Mess_Kanal> MessKanal { get; set; }
}
public class Mess_Kanal
{
public string ID { get; set; }
public string ModulID { get; set; }
public List<LogMess_Daten> LogMessDaten { get; set; }
}
public class LogMess_Daten
{
public string KanalID { get; set; }
public string Zeitstempel { get; set; }
}
public class RootObject
{
public int ID_Project { get; set; }
public string Name_Project { get; set; }
public int Receiver_ID { get; set; }
public string Receiver_Name { get; set; }
public int UserID { get; set; }
public User_Role UserRole { get; set; }
public Stand_Orte Standorte { get; set; }
}
I have an issue with accessing the 3rd level data elements.
For Eg., I am able to get the values uptil Project-> Stand_Orte-> Modul. but after that Project-> Stand_Orte-> Modul-> MessKanal Throws an error in PHP as " Trying to get property of non-object ".
I tried the following:
$phpArray['project']->Standorte[0]->modul[0]->MessKanal[0]->ID
$messkanals=$phpArray->Standorte->modul->MessKanal;
And then used a "foreach ($messkanals as $messkanal)" to insert MessKanal data into MYSQL.
it gives me the following errors respectively.
Cannot use object of type stdClass as array
Trying to get property of non-object
does anyone have any idea?
Thanks,
Revathy

entity framework linq include and grouping [duplicate]

This question already has answers here:
Why doesn't Include have any effect?
(2 answers)
Closed 1 year ago.
I'm trying to to do include and group in in one sentence
var instanceIdList = context.
Tracks.
Include("Services").
GroupBy(x => x.ServiceId).
Take(top);
but when I check the result at debug I cant see any of the include values
I tried to do in another way
var objectContext = ((IObjectContextAdapter)context).ObjectContext;
var set = objectContext.CreateObjectSet<Track>();
var instanceIdList = set.Include("Services").GroupBy(x => x.ServiceId);
this is the classes :
Track
public partial class Track
{
public long Id { get; set; }
public System.Guid ServiceId { get; set; }
public Nullable<System.Guid> ServiceInterfaceId { get; set; }
public Nullable<System.Guid> ProviderId { get; set; }
public System.Guid ServiceInstanceId { get; set; }
public System.Guid ActivityParentId { get; set; }
public System.Guid ActivityInstanceId { get; set; }
public int ActivityType { get; set; }
public int ServiceRole { get; set; }
public int TrackOrder { get; set; }
public System.DateTime Datetime { get; set; }
public Nullable<System.Guid> MessageId { get; set; }
public int Status { get; set; }
public Nullable<int> ESBErrorCode { get; set; }
public Nullable<int> ESBTecnicalErrorCode { get; set; }
public string ErrorDescription { get; set; }
public string PortName { get; set; }
public string MachineName { get; set; }
public string ConsumerId { get; set; }
public string ExternalId { get; set; }
public string ConsumerMachineName { get; set; }
public int ServiceBehavior { get; set; }
public virtual Message Message { get; set; }
}
Service
public partial class Service
{
public Service()
{
this.Providers = new HashSet<Provider>();
this.ServiceInterfaces = new HashSet<ServiceInterface>();
}
public System.Guid ServiceId { get; set; }
public string ServiceName { get; set; }
public string ServiceNumber { get; set; }
public Nullable<System.Guid> ModelSchemaId { get; set; }
public virtual ICollection<Provider> Providers { get; set; }
public virtual ICollection<ServiceInterface> ServiceInterfaces { get; set; }
}
but the result is the same
thanks
miki
You also need to put include in the end.
Like this...
var instanceIdList = context.Tracks
.GroupBy(x => x.ServiceId)
.Take(top)
.Include("Services");
You have not defined any navigation property for Services in your Track class, you need to add the following property.
public virtual ICollection<Service> Services { get; set; }
Your Track class has no member accessor called service, so
Include("Services")
won't work.
You need to link to Service from Track, e.g.
public Service Services {get;set;}

Categories

Resources