ASP.NET Core AutoMapper configuration error - c#

I am trying to map an entity with a model but it's giving an error how can I check which property is causing the error?
Error: AutoMapper.AutoMapperMappingException: 'Error mapping types.'
AutoMapperMappingException: Missing type map configuration or unsupported mapping.
This exception was originally thrown at this call stack:
AutoMapper.Mapper.MapCore<TSource, TDestination>(TSource, TDestination, AutoMapper.ResolutionContext, System.Type, System.Type, AutoMapper.MemberMap)
AutoMapper.Mapper.AutoMapper.IInternalRuntimeMapper.Map<TSource, TDestination>(TSource, TDestination, AutoMapper.ResolutionContext, System.Type, System.Type, AutoMapper.MemberMap)
AutoMapper.ResolutionContext.MapInternal<TSource, TDestination>(TSource, TDestination, AutoMapper.MemberMap)
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<Account, AccountModel>();
CreateMap<AccountModel, Account>();
CreateMap<ServicePlan, ServicePlanModel>()
.ForMember(ServicePlanModel => ServicePlanModel.ServicePlanDetails, opt => opt.MapFrom(src => src.ServicePlanDetails.ToList()))
.ForMember(dest => dest.Lines, opt => opt.MapFrom(src => src.NLines ?? default))
.ForMember(dest => dest.StartDate, opt => opt.MapFrom(src => src.DateStart))
.ForMember(dest => dest.EndDate, opt => opt.MapFrom(src => src.DateEnd))
.ForMember(dest => dest.MonthlyCharges, opt => opt.MapFrom(src => src.AmountMonthly))
.ForMember(dest => dest.OneTimeCharges, opt => opt.MapFrom(src => src.AmountOnetime));
}
}
public async Task<List<ServicePlanModel>> GetServicePlansWithDetails(long accountId)
{
var plan = mapper.Map<ServicePlan, ServicePlanModel>(servicePlan);
}
public partial class ServicePlan
{
public ServicePlan()
{
ServicePlanDetails = new HashSet<ServicePlanDetail>();
}
public long PlanId { get; set; }
public decimal PhoneId { get; set; }
public byte? NLines { get; set; }
public DateTime? DateStart { get; set; }
public DateTime? DateEnd { get; set; }
public decimal? AmountMonthly { get; set; }
public decimal? AmountOnetime { get; set; }
public string? ContractType { get; set; }
public string? CallerId { get; set; }
public bool? Active { get; set; }
public short? ResellerId { get; set; }
public int? OnetimeInvoiceNo { get; set; }
public bool? IsRequest { get; set; }
public string? RequestType { get; set; }
public string? NewValue { get; set; }
public DateTime? RequestDate { get; set; }
public string? RequestBy { get; set; }
public bool? IsRejected { get; set; }
public bool? IsApproved { get; set; }
public DateTime? ApprovedWhen { get; set; }
public string? ApprovedBy { get; set; }
public string? Comments { get; set; }
public string? AdditionalDetails { get; set; }
public string? VideoTronId { get; set; }
public string? Zone { get; set; }
public string? PrevProvider { get; set; }
public bool? Charge911Tax { get; set; }
public string? ContractTerms { get; set; }
public long? ContractId { get; set; }
public int AllowedBandwidth { get; set; }
public DateTime? ServiceStartDate { get; set; }
public string? AppointmentTime { get; set; }
public DateTime? AppointmentEmailSentOn { get; set; }
public string? TrackingNumber { get; set; }
public bool? HasNumberPort { get; set; }
public DateTime? EstPortDate { get; set; }
public DateTime? PortCompletedOn { get; set; }
public bool? IsExGbchargesLimited { get; set; }
public decimal? ExGbchagesLimitAmt { get; set; }
public bool? IsPreVisitSch { get; set; }
public DateTime? PreVisitSchDate { get; set; }
public string? PreVisitSchTime { get; set; }
public bool? MoniterBwUsage { get; set; }
public int? BwWarnLimit { get; set; }
public string? DslaccountId { get; set; }
public string? BellGisId { get; set; }
public string? DslPassword { get; set; }
public bool? IsPasswordPassed { get; set; }
public bool? IsDslUserPassed { get; set; }
public string? CogecoId { get; set; }
public int? ServiceProviderId { get; set; }
public string? RogersId { get; set; }
public decimal? InternetSpeed { get; set; }
public bool? ModemRental { get; set; }
public bool? RouterRental { get; set; }
public bool? Atarental { get; set; }
public string? DslaccountDomain { get; set; }
[NotMapped]
public virtual ICollection<ServicePlanDetail> ServicePlanDetails { get; set; }
}
public class ServicePlanModel
{
public ServicePlanModel()
{
ServicePlanDiscounts = new List<ServicePlanDiscount>();
ServicePlanDetails = new List<ServicePlanDetail>();
}
[Key]
public Int64 PlanId { get; set; }
public Int64? ContractId { get; set; }
public int ResellerId { get; set; }
public Int64 PhoneId { get; set; }
public bool IsPhone { get; set; }
public Int32? OneTimeInvoiceId { get; set; }
public UInt16 Lines { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public Decimal MonthlyCharges { get; set; }
public Decimal OneTimeCharges { get; set; }
public String ContractType { get; set; }
public String CallerId { get; set; }
public Boolean IsActive { get; set; }
public Boolean IsRequest { get; set; }
public Boolean IsRejected { get; set; }
public Boolean IsApproved { get; set; }
public Boolean Charge911Tax { get; set; }
public DateTime ApprovedOn { get; set; }
public String ApprovedBy { get; set; }
public String Comments { get; set; }
public String ContractTerms { get; set; }
public String AdditionalDetails { get; set; }
public String VideoTronId { get; set; }
public String Zone { get; set; }
public String PreviousProvider { get; set; }
public String RequestType { get; set; }
public String NewValue { get; set; }
public DateTime? RequestDate { get; set; }
public String RequestedBy { get; set; }
//public PhoneNumber PhoneNumber { get; set; }
public List<ServicePlanDetail> ServicePlanDetails { get; set; }
public List<ServicePlanDiscount> ServicePlanDiscounts { get; set; }
public bool IsLandLinePlan
{
get
{
if (ServicePlanDetails != null)
{
return ServicePlanDetails.Any(spd => new String[] { "landline-r", "landline-b", "plan_10103", "plan_10104", "plan_10105" }.Contains(spd.ServiceCode));
}
return false;
}
}
public String ServicePlanName
{
get
{
if (ServicePlanDetails != null && ServicePlanDetails.Count > 0)
{
var plan = ServicePlanDetails.SingleOrDefault(spd => spd.IsPlan);
if (plan != null)
{
if (IsPhone)
{
return String.Format("{0} ({3}) ({1} x {2})", plan.ServiceTitle, plan.UnitPrice.ToString("N2"), plan.Quantity, PhoneId.ToString("###-###-####"));
}
return String.Format("{0} ({1} x {2})", plan.ServiceTitle, plan.UnitPrice.ToString("N2"), plan.Quantity);
}
}
return String.Empty;
}
}
public String MonthlyChargesDetails
{
get
{
if (ServicePlanDetails != null && ServicePlanDetails.Count > 0)
{
var items = ServicePlanDetails.Where(spd => spd.IsPlan == false & spd.UnitPrice > 0 & spd.ServiceType.Equals(Constants.SERVICE_TYPE_MONTHLY)).ToList();
var details = new StringBuilder();
foreach (var spd in items)
{
details.Append(String.Format("{0} ({1} x {2}) ", spd.ServiceTitle, spd.UnitPrice.ToString("N2"),
spd.Quantity));
}
return details.ToString();
}
return String.Empty;
}
}
//public String OnetimeChargesDetails
//{
// get
// {
// if (ServicePlanDetails != null && ServicePlanDetails.Count > 0)
// {
// var items = ServicePlanDetails.Where(spd => spd.IsPlan == false & spd.UnitPrice > 0 & spd.ServiceType.Equals(Constants.SERVICE_TYPE_ONETIME)).ToList();
// var details = new StringBuilder();
// foreach (var spd in items)
// {
// details.Append(String.Format("{0} ({1} x {2}) ", spd.ServiceTitle, spd.UnitPrice.ToString("N2"),
// spd.Quantity));
// }
// return details.ToString();
// }
// return String.Empty;
// }
//}
public List<ServicePlanDetail> OnetimeChargesDetails
{
get
{
if (ServicePlanDetails != null && ServicePlanDetails.Count > 0)
{
return ServicePlanDetails.Where(spd => spd.IsPlan == false & spd.ServiceType.Equals(Constants.SERVICE_TYPE_ONETIME)).ToList();
}
return null;
}
}
public List<ServicePlanDetail> FreeServicesDetails
{
get { return ServicePlanDetails != null ? ServicePlanDetails.Where(s => s.UnitPrice == 0 && !s.ServiceType.Equals("month")).ToList() : null; }
}
public List<ServicePlanDetail> DiscountedServicesDetail
{
get
{
return ServicePlanDetails != null ?
ServicePlanDetails.Where(s => s.ResellerService != null && s.UnitPrice < s.ResellerService.SuggestedPrice && !s.ServiceType.Equals("month")).ToList() : null;
}
}
public string Modem_MAC { get; set; }
public string TrackingNumber { get; set; }
}
I tried debugging but could not find the error.

Take a look at the source for AutoMapperMappingException. There are a number of properties on the exception that can be examined while under a debugger.
From the source...
public TypePair? Types { get; set; }
public TypeMap TypeMap { get; set; }
public MemberMap MemberMap { get; set; }
These properties are used to create the string for the Message property.
If for some reason that doesn't give you enough information, a way more intensive and semi-destructive way (have a backup of your source) is to cut half of the properties from the source/target types and see if the error still occurs. If yes, cut in half again, if no take the other properties and try again.
Basically, you are doing a binary search to narrow down the problem until it becomes obvious.

Related

Entity Framework 6.1: update child ICollection when the parent entity is created

I have to pass some data from a source DB to another target DB both handled using Entity Framework just with two different DbContexts.
This is my code:
internal async static Task UploadNewsList(DateTime dataStart, TextWriter logger)
{
try
{
NumberFormatInfo provider = new NumberFormatInfo();
provider.NumberDecimalSeparator = ".";
using (BDContentsDataModel buffettiContext = new BDContentsDataModel())
{
List<News> newsList = buffettiContext.News.Where(x => x.Online && x.DataPub >= dataStart.Date).ToList();
using (DirectioDBContext directioContext = new DirectioDBContext())
{
foreach(News buffettiNews in newsList)
{
bool hasAuth = false;
List<DirectioAutore> listAutori = null;
List<DirectioAutore> listAutoriFinal = new List<DirectioAutore>();
if (buffettiNews.AutoreList?.Count > 0)
{
hasAuth = true;
listAutori = EntitiesHelper.GetAutoriDirectio(buffettiNews.AutoreList.ToList(), directioContext);
foreach (var autore in listAutori)
{
int dirAuthId = 0;
bool exist = false;
foreach (var dirAut in directioContext.Autori)
{
if (dirAut.Nome.IndexOf(autore.Nome, StringComparison.InvariantCultureIgnoreCase) >= 0 &&
dirAut.Cognome.IndexOf(autore.Cognome, StringComparison.InvariantCultureIgnoreCase) >= 0)
{
exist = true;
dirAuthId = dirAut.Id;
}
}
//directioContext.Autori.
//Where(x => autore.Cognome.ToLowerInvariant().Contains(x.Cognome.ToLowerInvariant()) &&
// autore.Nome.ToLowerInvariant().Contains(x.Nome.ToLowerInvariant())).Any();
if (!exist)
{
directioContext.Autori.Add(autore);
directioContext.SaveChanges();
}
else
{
autore.Id = dirAuthId;
}
listAutoriFinal.Add(autore);
}
}
DirectioNews directioNews = EntitiesHelper.CreateDirectioNewsModel(buffettiNews);
if (hasAuth)
directioNews.AutoreList = listAutoriFinal;
if (directioNews == null)
throw new Exception("[News] - Trasformazione entità fallita");
directioContext.News.Add(directioNews);
await directioContext.SaveChangesAsync();
}
}
}
}
catch (Exception ex)
{
logger.WriteLine(ex.Message);
throw ex;
}
}
This is the target DbContext:
public class DirectioDBContext : DbContext
{
public DirectioDBContext() : base("name=DirectioCMSDataModel") { }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// ...
modelBuilder.Entity<DirectioNews>()
.HasMany(s => s.AutoreList)
.WithMany(x => x.News)
.Map(cs =>
{
cs.MapLeftKey("Autore_Id");
cs.MapRightKey("News_Id");
cs.ToTable("NewsAutore");
});
}
public virtual DbSet<DirectioNews> News { get; set; }
public virtual DbSet<DirectioVideo> Video { get; set; }
public virtual DbSet<DirectioMedia> Media { get; set; }
public virtual DbSet<DirectioAutore> Autori { get; set; }
public virtual DbSet<DirectioVideoAutori> VideoAutori { get; set; }
}
This is the interested target Parent Model:
[Table("News")]
public partial class DirectioNews
{
[Key]
public int Id { get; set; }
public string Titolo { get; set; }
public int IdDocType { get; set; }
public string Abstract { get; set; }
public string Testo { get; set; }
[Required]
public DateTime DataPub { get; set; }
public int IdUmbraco { get; set; }
public int CreatedById { get; set; }
public DateTime CreateDate { get; set; }
public int? UpdateById { get; set; }
public DateTime? UpdateDate { get; set; }
public int? DeletedById { get; set; }
public DateTime? DeletedDate { get; set; }
public int? ResumedById { get; set; }
public DateTime? ResumedDate { get; set; }
public int? PublishedById { get; set; }
public DateTime? PublishedDate { get; set; }
public int? UnpublishedById { get; set; }
public DateTime? UnpublishedDate { get; set; }
public DateTime? PublishedFrom { get; set; }
public DateTime? PublishedTo { get; set; }
public bool Online { get; set; }
public bool APagamento { get; set; }
public int IdConsulenzaOld { get; set; }
public bool IsDeleted { get; set; }
public virtual ICollection<DirectioAutore> AutoreList { get; set; }
public bool IsFromOtherCMS { get; set; } = false;
public string Name { get; set; }
public int? NodeId { get; set; }
public int SortOrder { get; set; } = 0;
public Guid PlatformGuid { get; set; }
public Guid SourceGuid { get; set; }
// Permette l'accesso anche senza login
public bool FreeWithoutLogin { get; set; }
// nasconde dalla visualizzazione della lista normale del frontend, visibile solo attraverso l'etichetta campagna
public bool HideFromList { get; set; }
#region parametri per riferimenti temporali
public int? Day { get; set; } = null;
public int? Month { get; set; } = null;
public int? Year { get; set; } = null;
#endregion
public int? MediaId
{
get; set;
}
}
And this is the target Child model
[Table("Autori")]
public class DirectioAutore
{
[Key]
public int Id { get; set; }
public string Nome { get; set; }
[Required]
public string Cognome { get; set; }
public string DescrizioneBreve { get; set; }
public string Descrizione { get; set; }
public string Email { get; set; }
public string Immagine { get; set; }
public string Tipo { get; set; } // Maschio Femmina Team
public string Twitter { get; set; }
public int IdUmbraco { get; set; }
public bool Online { get; set; }
public DateTime? PublishedFrom { get; set; }
public DateTime? PublishedTo { get; set; }
public int IdOld { get; set; }
public bool IsDeleted { get; set; }
public int? NodeId { get; set; }
public string Name { get; set; }
public int CreatedById { get; set; } = 1;
public DateTime CreateDate { get; set; }
public int? UpdateById { get; set; }
public DateTime? UpdateDate { get; set; }
public int? DeletedById { get; set; }
public DateTime? DeletedDate { get; set; }
public int? ResumedById { get; set; }
public DateTime? ResumedDate { get; set; }
public int? PublishedById { get; set; }
public DateTime? PublishedDate { get; set; }
public int? UnpublishedById { get; set; }
public DateTime? UnpublishedDate { get; set; }
public string MetaaDescrBreve { get; set; }
public int? MediaId
{
get; set;
}
public Guid PlatformGuid { get; set; }
public Guid SourceGuid { get; set; }
public string MetaTitle { get; set; }
public string MetaDescription { get; set; }
public virtual ICollection<DirectioNews> News { get; set; }
}
EntityFramework generated this table to handle this many-to-many relation:
When it saves the entity, it goes into the catch statement and show this error:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.NewsAutore_dbo.Autori_Autore_Id". The conflict occurred in database "DirectioContentsCMS_Stage_20201102", table "dbo.Autori", column 'Id'
What could be the problem?
Thank you so much
[SOLVED]
I was wrongly pointing LeftKey and RightKey into the DbContext, they was not pointing to the correct FKs.
I just inverted FKs:
modelBuilder.Entity<DirectioNews>()
.HasMany(s => s.AutoreList)
.WithMany(x => x.News)
.Map(cs =>
{
cs.MapLeftKey("Autore_Id");
cs.MapRightKey("News_Id");
cs.ToTable("NewsAutore");
});
instead of
modelBuilder.Entity<DirectioNews>()
.HasMany(s => s.AutoreList)
.WithMany(x => x.News)
.Map(cs =>
{
cs.MapLeftKey("News_Id");
cs.MapRightKey("Autore_Id");
cs.ToTable("NewsAutore");
});
Because MapLeftKey points to the parent entity of the navigation property specified in the HasMany method and MapRightKey points to the parent entity of the navigation property specified in the WithMany. I was doing exactly the opposite.
Then i moved the association after actually saving the news to prevent multiple authors creation:
// ...
DirectioNews directioNews = EntitiesHelper.CreateDirectioNewsModel(buffettiNews);
if (directioNews == null)
throw new Exception("[News] - Trasformazione entità fallita");
directioContext.News.Add(directioNews);
directioContext.SaveChanges();
if (hasAuth)
{
List<int> ids = listAutori.Select(s => s.Id).ToList();
List<DirectioAutore> r = directioContext.Autori.Where(x => ids.Contains(x.Id)).ToList();
directioNews.AutoreList = r;
directioContext.SaveChanges();
}

Getting Stackoverflow exception when mapping using automapper

I am getting StackOverflow exception while passing the objects using automapper.
This is before mapping getting result accurately
Here is the error where exception comes when mapping
My Domain Model class is
public class Appointment
{
[Key]
public int AppointmentID { get; set; }
public int Serial { get; set; }
public int AppointmentTypeID { get; set; } = 2;
public DateTime CreatedAt { get; set; }
public string CreatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
public string UpdatedBy { get; set; }
[ForeignKey("CreatedBy")]
public virtual User User { get; set; }
public virtual ICollection<VisitRequest> VisitRequests { get; set; }
[ForeignKey("AppointmentTypeID")]
public virtual VisitPurpose VisitPurpose { get; set; }
public virtual ICollection<AppointmentStatus> AppointmentStatuses { get; set; }
}
My View Model Classes are
public class ApproveAppointmentViewModel
{
[Key]
public int AppointmentID { get; set; }
public int Serial { get; set; }
public int AppointmentTypeID { get; set; }
public virtual ICollection<ApproveAppointmentVisitRequestViewModel> VisitRequests { get; set; }
public virtual ICollection<ApproveAppointmentStatusViewModel> AppointmentStatuses { get; set; }
}
public class ApproveAppointmentVisitRequestViewModel
{
[Key]
public int VisitRequestID { get; set; }
public bool SendSMS { get; set; }
public int? PurposeID { get; set; }
public string PurposeDescription { get; set; }
public string Attachment { get; set; }
public int VisitorID { get; set; }
public int? AppointmentID { get; set; }
public virtual ApproveAppointmentViewModel Appointment { get; set; }
public virtual ApproveAppointmentVisitorViewModel Visitor { get; set; }
}
public class ApproveAppointmentVisitorViewModel
{
[Key]
public int? VisitorID { get; set; }
public string NationalID { get; set; }
public string FullName { get; set; }
public int Gender { get; set; }
public string Job { get; set; }
public string Type { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
public virtual ICollection<ApproveAppointmentVisitRequestViewModel> VisitRequests { get; set; }
}
public class ApproveAppointmentStatusViewModel
{
public int StatusID { get; set; }
public int AppointmentID { get; set; }
public int StatusCode
{
get
{
return 1;
}
}
public DateTime ValidFrom
{
get
{
return DateTime.UtcNow.AddHours(3);
}
}
[UnavailableDate]
public DateTime? AppointmentDateTime
{
get
{
if (AppointmentDate != null)
{
if (AppointmentTime != null && AppointmentTime.Length > 0)
return new DateTime(AppointmentDate.Value.Year, AppointmentDate.Value.Month, AppointmentDate.Value.Day, int.Parse(AppointmentTime.Split(':')[0]), int.Parse(AppointmentTime.Split(':')[1]), 0);
else
return new DateTime(AppointmentDate.Value.Year, AppointmentDate.Value.Month, AppointmentDate.Value.Day);
}
else
{
return null;
}
}
}
public DateTime? AppointmentDate { get; set; }
public DateTime? _AppointmentDate { get; set; }
[Display(Name = "التاريخ")]
public string AppointmentDateHijri
{
get
{
if (AppointmentDate.HasValue)
return AppointmentDate.Value.ConvertToHijriString();
return null;
}
set
{
if (value != null)
{
var generalDate = new DateTime(int.Parse(value.Split('/')[0]), int.Parse(value.Split('/')[1]), int.Parse(value.Split('/')[2]));
AppointmentDate = generalDate.Year > 1500 ? generalDate : generalDate.ConvertToGeorgian();
}
else
AppointmentDate = null;
}
}
[Display(Name = "ملاحظة الإعتماد")]
public string StatusNote { get; set; }
[Required(ErrorMessage = "يجب تحديد الوقت المعتمد")]
[Display(Name = "الوقت")]
public string AppointmentTime { get; set; }
[Range(0, 60, ErrorMessage = "أقل مدة للزيارة 10 دقائق واقصى مدة 60 أو مفتوح")]
[Display(Name = "المدة (دقائق)")]
public int? AppointmentDuration { get; set; }
public virtual ApproveAppointmentViewModel Appointment { get; set; }
}
Controller code is
var AppointmentRequest = db.Appointments.Where(p => p.AppointmentID == id).Include(m => m.VisitRequests).Include(m => m.AppointmentStatuses).FirstOrDefault();
here i am getting exception when mapping using automapper
var vmodel = Mapper.Map<ApproveAppointmentViewModel>(AppointmentRequest);

Automapper 6.0.2.0, Mapper.Map() throws StackOverflow when mapping Child Entities

Getting straight to the point, I've got the following Models:
public abstract class ControlData
{
public DateTime CreatedDate { get; set; }
public int CreatedById { get; set; }
[ForeignKey("CreatedById")]
public Collaborator CreatedBy { get; set; }
public DateTime? UpdatedDate { get; set; }
public int? UpdatedById { get; set; }
[ForeignKey("UpdatedById")]
public Collaborator UpdatedBy { get; set; }
}
[Table("My_Position_Table")]
public class Position : ControlData
{
[Key]
[Column("PositionId")]
public int Id { get; set; }
[Column("PositionStatusId")]
public int StatusId { get; set; }
[ForeignKey("StatusId")]
public PositionStatus Status { get; set; }
public int OpportunityId { get; set; }
[ForeignKey("OpportunityId")]
public Opportunity Opportunity { get; set; }
public int Total { get; set; }
[Column("PositionDurationId")]
public int DurationId { get; set; }
[ForeignKey("DurationId")]
public PositionDuration Duration { get; set; }
public DateTime StartDate { get; set; }
//TODO Agregar las otras propiedades con sus respectivos catalogos
public string PracticeId { get; set; }
[ForeignKey("PracticeId")]
public Practice Practice { get; set; }
public int RoleId { get; set; }
[ForeignKey("RoleId")]
public PersonRole Role { get; set; }
public int PlatformId { get; set; }
[ForeignKey("PlatformId")]
public Platform Platform { get; set; }
public int LevelId { get; set; }
[ForeignKey("LevelId")]
public Level Level { get; set; }
public int EnglishLevelId { get; set; }
[ForeignKey("EnglishLevelId")]
public EnglishLevel EnglishLevel { get; set; }
public string CountryId { get; set; }
public int LocationId { get; set; }
[ForeignKey("LocationId")]
public Location Location { get; set; }
public int? OfficeId { get; set; }
public int OperationId { get; set; }
[ForeignKey("OperationId")]
public Person Operation { get; set; }
public int? EvaluatorId { get; set; }
[ForeignKey("EvaluatorId")]
public Collaborator Evaluator { get; set; }
public int? SourcerId { get; set; }
[ForeignKey("SourcerId")]
public Collaborator Sourcer { get; set; }
public List<Candidate> Candidates { get; set; }
public int? PositionCancellationReasonId { get; set; }
[ForeignKey("PositionCancellationReasonId")]
public PositionCancellationReason CancellationReason { get; set; }
public string CancellationComments { get; set; }
public int? CancellationById { get; set; }
[ForeignKey("CancellationById")]
public Collaborator CancellationBy { get; set; }
public DateTime? CancellationDate { get; set; }
public bool Active { get; set; }
public bool WhereAvailable { get; set; }
public bool RequestAsset { get; set; }
public string CityZone { get; set; }
public string TravelsTo { get; set; }
public string Description { get; set; }
public string SpecificationFile { get; set; }
public int PositionPriorityId { get; set; }
public int? SourcingGroupId { get; set; }
}
[Table("My_Opportunity_Table")]
public class Opportunity : ControlData
{
[Column("OpportunityId")]
[Key]
public int Id { get; set; }
[Column("OpportunityStatusId")]
public int StatusId { get; set; }
[ForeignKey("StatusId")]
public OpportunityStatus Status { get; set; }
public string ProjectId { get; set; }
[ForeignKey("ProjectId")]
public Project Project { get; set; }
public string MarketId { get; set; }
[ForeignKey("MarketId")]
public Market Market { get; set; }
public string CustomerId { get; set; }
[ForeignKey("CustomerId")]
public Customer Customer { get; set; }
public string Name { get; set; }
[Column("OpportunityTypeId")]
public int TypeId { get; set; }
[ForeignKey("TypeId")]
public OpportunityType Type { get; set; }
[Column("OpportunityPriorityId")]
public int PriorityId { get; set; }
[ForeignKey("PriorityId")]
public OpportunityPriority Priority { get; set; }
public int? OpportunityCancellationReasonId { get; set; }
[ForeignKey("OpportunityCancellationReasonId")]
public OpportunityCancellationReason CancellationReason { get; set; }
public string CancellationComments { get; set; }
public int? CancellationById { get; set; }
[ForeignKey("CancellationById")]
public Collaborator CancellationBy { get; set; }
public DateTime? CancellationDate { get; set; }
public bool Active { get; set; }
public List<OpportunityRole> OpportunityRoles { get; set; }
public List<Position> Positions { get; set; }
}
And also, I've got their equivalents in DTO's:
public abstract class ControlDataDTO
{
public DateTime CreatedDate { get; set; }
public int CreatedById { get; set; }
public CollaboratorPlainDTO CreatedBy { get; set; }
public DateTime? UpdatedDate { get; set; }
public int? UpdatedById { get; set; }
public CollaboratorPlainDTO UpdatedBy { get; set; }
}
public class PositionDTO: ControlDataDTO
{
public int Id { get; set; }
public int StatusId { get; set; }
public PositionStatusDTO Status { get; set; }
public int OpportunityId { get; set; }
public OpportunityDTO Opportunity { get; set; }
public int Total { get; set; }
public int DurationId { get; set; }
public PositionDurationDTO Duration { get; set; }
public DateTime StartDate { get; set; }
public string PracticeId { get; set; }
public PracticeDTO Practice { get; set; }
public int RoleId { get; set; }
public PersonRoleDTO Role { get; set; }
public int PlatformId { get; set; }
public PlatformDTO Platform { get; set; }
public int LevelId { get; set; }
public LevelDTO Level { get; set; }
public int EnglishLevelId { get; set; }
public EnglishLevelDTO EnglishLevel { get; set; }
public string CountryId { get; set; }
public int LocationId { get; set; }
public LocationDTO Location { get; set; }
public int? OfficeId { get; set; }
public int OperationId { get; set; }
public PersonDTO Operation { get; set; }
public string OperationIS { get; set; }
public bool WhereAvailable { get; set; }
public bool RequestAsset { get; set; }
public string CityZone { get; set; }
public string TravelsTo { get; set; }
public string Description { get; set; }
public int CandidatesAccepted { get; set; }
public int CandidatesRejected { get; set; }
public int CandidatesWaiting { get; set; }
public bool HasCandidatesWaiting { get; set; }
public int TotalCandidates { get; set; }
public string SpecificationFile { get; set; }
public int? EvaluatorId { get; set; }
public int? SourcerId { get; set; }
public CollaboratorDTO Sourcer { get; set; }
public int? SourcingGroupId { get; set; }
public PositionCancellationReasonDTO CancellationReason { get; set; }
}
public class OpportunityDTO: ControlDataDTO
{
public int Id { get; set; }
public int StatusId { get; set; }
public OpportunityStatusDTO Status { get; set; }
public string ProjectId { get; set; }
public ProjectDTO Project { get; set; }
public string MarketId { get; set; }
public MarketDTO Market { get; set; }
public string CustomerId { get; set; }
public CustomerDTO Customer { get; set; }
public string Name { get; set; }
public int TypeId { get; set; }
public OpportunityTypeDTO Type { get; set; }
public int PriorityId { get; set; }
public OpportunityPriorityDTO Priority { get; set; }
public int? OpportunityCancellationReasonId { get; set; }
public OpportunityCancellationReasonDTO CancellationReason { get; set; }
public string CancellationComments { get; set; }
public int? CancellationById { get; set; }
public CollaboratorPlainDTO CancellationBy { get; set; }
public DateTime? CancellationDate { get; set; }
public CollaboratorDTO Responsible { get; set; }
public List<OpportunityRoleDTO> OpportunityRoles { get; set; }
public int TotalPositions { get; set; }
public bool CandidatesWarning { get; set; }
public bool Active { get; set; }
public List<PositionDTO> Positions { get; set; }
}
For this mapping initialization we are using Profiles, like this way:
public class AutoMapperConfig
{
public static void RegisterMappings()
{
Mapper.Initialize(cfg =>
{
// ...
cfg.AddProfile<OpportunityMappingProfile>();
// ...
});
}
}
public class OpportunityMappingProfile : Profile
{
public OpportunityMappingProfile()
{
CreateMap<Opportunity, OpportunityDTO>()
.ForMember(x => x.Responsible, x => x.MapFrom(c => GetFromOpportunityRoles(c.OpportunityRoles, Constants.OpportunityResponsible)))
.ForMember(x => x.TotalPositions, x => x.MapFrom(c => c.Positions.Count()))
.ForMember(x => x.CandidatesWarning, x => x.MapFrom(c => c.Positions.Count() > 0 ?
c.Positions.Any(pos => pos.Candidates.Any(cand => cand.StatusId == 3)) :
false))
.ForMember(x => x.CreatedBy, x => x.MapFrom(c => Mapper.Map<CollaboratorPlainDTO>(c.CreatedBy)))
.ForMember(x => x.UpdatedBy, x => x.MapFrom(c => Mapper.Map<CollaboratorPlainDTO>(c.UpdatedBy)))
.ForMember(x => x.Positions, x => x.MapFrom(c => Mapper.Map<List<PositionDTO>>(c.Positions))).PreserveReferences(); --> Even using this method, StackOverflow exception is still occurring...
CreateMap<OpportunityDTO, Opportunity>()
.ForMember(x => x.CancellationReason, x => x.Ignore())
.ForMember(x => x.CreatedBy, x => x.Ignore())
.ForMember(x => x.UpdatedBy, x => x.Ignore())
.ForMember(x => x.Positions, x => x.Ignore());
}
private Collaborator GetFromOpportunityRoles(List<OpportunityRole> opportunityRoles, string rol)
{
var opportunityRole = opportunityRoles.FirstOrDefault(opp => opp.ProjectRoleTypeId == rol);
return opportunityRoles != null ? opportunityRole.Collaborator : null;
}
}
And finally, the logic that does the mapping where I'm getting the commented error...
public class OpportunityLogic : IOpportunityLogic
{
// Properties...
public OpportunityLogic(parameters list here, though irrelevant for this example)
{
// ...
}
public ActionResponse<List<OpportunityDTO>> GetOpportunitiesWithPositions(int personId)
{
// Information is retrieved from DB, here...
List<Opportunity> listOpportunities = opportunityRepository.Get(
opp => opp.Status,
opp => opp.Market,
opp => opp.Customer,
opp => opp.Type,
opp => opp.Project,
opp => opp.Status,
opp => opp.Positions,
opp => opp.Positions.Select(pos => pos.Candidates),
opp => opp.Positions.Select(pos => pos.Status),
opp => opp.Positions.Select(pos => pos.Practice),
opp => opp.Positions.Select(pos => pos.Role),
opp => opp.Positions.Select(pos => pos.Platform),
opp => opp.Positions.Select(pos => pos.Sourcer));
// After having retrieved data, here I re-define my model.
listOpportunities = listOpportunities
.Where( opp => opp.StatusId == (int)Constants.OpportunityStatus.Open &&
opp.Active == true &&
opp.Positions.Any(pos => pos.StatusId == (int)Constants.PositionStatus.Open &&
pos.Candidates.Any(can => can.PersonId == personId &&
can.Active == true &&
(can.StatusId == (int)Constants.CandidateStatus.Lead ||
can.StatusId == (int)Constants.CandidateStatus.Waiting))))
.ToList();
// MY PROBLEM IS HERE....
var mappedOpportunities = Mapper.Map<List<OpportunityDTO>>(listOpportunities);
return new ActionResponse<List<OpportunityDTO>> (mappedOpportunities);
}
}
My problem starts when trying to map my Model (List) to the DTO (List); the error is the well-known "StackOverflow Exception". If I'm using the "PreserveReferences()" method, why is still throwing the same exception?. The same goes for "MaxDepth() method", after having tried different depth levels (1,2,3...).
I've spent too many hours trying to solve this issue and to be honest, I'm out of ideas already. If anyone has an idea what to do here, I'll be really grateful.
Thanks and advance & regards!!
Starting from 6.1.0 PreserveReferences is set automatically at config time whenever the recursion can be detected statically. If that doesn't happen in your case, open an issue with a full repro and we'll look into it.
http://automapperdocs.readthedocs.io/en/latest/5.0-Upgrade-Guide.html#circular-references
But you have to remove the Map calls inside the MapFroms. Those ForMember-s are not needed.
The issue here is that I was missing another Mapping Profile that needed to preserve its references, but had not mentioned here, since I was missing that part and that was the one that had causing me all the issues.

Entity Framework is entering duplicate on bulk inserts approach

I'm trying to use this reply https://stackoverflow.com/a/5942176/5741268 For bulk inserts. But this procedure is entering duplicate.
My Entities
public class Empresa
{
public int EmpresaId { get; set; }
public string CNPJ { get; set; }
public string CPF { get; set; }
public string IE { get; set; }
public string xNome { get; set; }
public string cMun { get; set; }
public string CNAE { get; set; }
//Endereço
public string COD_PAIS { get; set; }
public string UF { get; set; }
public string CEP { get; set; }
public string END { get; set; }
public string NUM { get; set; }
public string COMPL { get; set; }
public string BAIRRO { get; set; }
public string FONE { get; set; }
}
public class NFe
{
public int NFeId { get; set; }
//public int NFePartId { get; set; }
public string versao { get; set; }
public string chave { get; set; }
public string ide_mod { get; set; }
public string ide_serie { get; set; }
public string ide_nNF { get; set; }
public DateTime? ide_dEmi { get; set; }
public DateTime? ide_dSaiEnt { get; set; }
public string ide_tpNF { get; set; }
public decimal? TOTAIS_vBC { get; set; }
public decimal? TOTAIS_vICMS { get; set; }
public decimal? TOTAIS_vBCST { get; set; }
public decimal? TOTAIS_vST { get; set; }
public decimal? TOTAIS_vProd { get; set; }
public decimal? TOTAIS_vFrete { get; set; }
public decimal? TOTAIS_vSeg { get; set; }
public decimal? TOTAIS_vDesc { get; set; }
public decimal? TOTAIS_vII { get; set; }
public decimal? TOTAIS_vIPI { get; set; }
public decimal? TOTAIS_vPIS { get; set; }
public decimal? TOTAIS_vCOFINS { get; set; }
public decimal? TOTAIS_vOutro { get; set; }
public decimal? TOTAIS_vNF { get; set; }
public string infCpl { get; set; }
public bool cancelada { get; set; } = false;
public virtual NFePart NFePart { get; set; }
public virtual Empresa Empresa { get; set; }
public virtual ICollection<NFeItem> NFeItemLista { get; set; }
}
public class NFePart
{
public int NFePartId { get; set; }
public string NOME { get; set; }
public string COD_PAIS { get; set; }
public string CNPJ { get; set; }
public string IE { get; set; }
public string UF { get; set; }
public string CEP { get; set; }
public string END { get; set; }
public string NUM { get; set; }
public string COMPL { get; set; }
public string BAIRRO { get; set; }
public string COD_MUN { get; set; }
public string FONE { get; set; }
public virtual Empresa Empresa { get; set; }
public virtual ICollection<NFe> NFe { get; set; }
//Uso interno, não mapeado no banco de dados
[NotMapped]
public int COD_PART { get; set; }
}
Here is my code:
List<NFe> notas = new List<NFe>();
//populate notas
DataContext context = null;
try
{
List<Empresa> nEmpresas = notas.DistinctBy(x => new { x.Empresa.CNPJ }).Select(x => x.Empresa).ToList();
foreach (Empresa empresaToAdd in nEmpresas)
{
context = new DataContext();
context.Configuration.AutoDetectChangesEnabled = false;
int count = 0;
List<NFe> notasFilter;
notasFilter = notas.Where(x => x.Empresa.CNPJ == empresaToAdd.CNPJ).ToList();
int commitCount = 2000;
foreach (var notaInsert in notasFilter)
{
++count;
context = AddToContext(context, notaInsert, count, commitCount, true, notasFilter.Count);
}
}
}
finally
{
if (context != null)
context.Dispose();
}
My AddtoContext function
private static DataContext AddToContext(DataContext context, NFe entity, int count, int commitCount, bool recreateContext, int totalNfe)
{
//if has already inserted -> Attach entity.Empresa
if ((count > commitCount && commitCount != 0) || entity.Empresa.EmpresaId != 0)
{
context.Empresa.Attach(entity.Empresa);
}
if (context.NFePart.Any(p => p.CNPJ == entity.NFePart.CNPJ && p.Empresa.CNPJ == entity.Empresa.CNPJ))
{
context.NFePart.Attach(entity.NFePart);
}
context.Set<NFe>().Add(entity);
if (commitCount == 0 || count % commitCount == 0 || count == totalNfe)
{
context.SaveChanges();
if (recreateContext)
{
context.Dispose();
context = new DataContext();
context.Configuration.AutoDetectChangesEnabled = false;
}
}
return context;
}
After save changes, the EF insert duplicate
In the code I'm going through all have in "notas" and only filtering the "empresaToAdd" in question. but when the loop moves on to the next "empresaToAdd" it inserts again notes the previous company in the loop even using Dispose, and recreating the context
NFeItemMap
public class NFeItemMap : EntityTypeConfiguration<NFeItem>
{
public NFeItemMap()
{
ToTable("NFeItem");
HasKey(x => x.NFeItemId);
Property(x => x.infAdProd).HasColumnType("text").IsMaxLength();
//one-to-many
HasRequired(s => s.NFe)
.WithMany(s => s.NFeItemLista);
HasRequired(x => x.Empresa)
.WithMany();
}
}

how to make Value cannot be null, null

Im having a method like this
public List<GSMData> GetGSMList()
{
return meters.Select(x => x.Gsmdata.Last())
.ToList();
}
and i get a "Value cannot be null." exeption. How do i make it so the value can be null?
GSMData object
public class GSMData : Meter
{
public DateTime TimeStamp { get; set; }
public int SignalStrength { get; set; }
public int CellID { get; set; }
public int LocationAC { get; set; }
public int MobileCC { get; set; }
public int MobileNC { get; set; }
public string ModemManufacturer { get; set; }
public string ModemModel { get; set; }
public string ModemFirmware { get; set; }
public string IMEI { get; set; }
public string IMSI { get; set; }
public string ICCID { get; set; }
public string AccessPointName { get; set; }
public int MobileStatus { get; set; }
public int MobileSettings { get; set; }
public string OperatorName { get; set; }
public int GPRSReconnect { get; set; }
public string PAP_Username { get; set; }
public string PAP_Password { get; set; }
public int Uptime { get; set; }
}
you better check for Gsmdata having items or not
public List<GSMData> GetGSMList()
{
return meters.Where(x=>x.Gsmdata!=null && x.Gsmdata.Any()).Select(x => x.Gsmdata.Last())
.ToList();
}
I'm guessing your Gsmdata property is null.
In this case, you could use the Linq .Where() method, to make this:
public List<GSMData> GetGSMList()
{
return meters.Where(x => x.Gsmdata != null)
.Select(x => x.Gsmdata.Last())
.ToList();
}
But you should clarify what exactly is null for better answers.
Try excluding null items by filtering the list immediately, and before doing the select.
public List GetGSMList()
{
return meters.Where(x=> x.Gsmdata != null).Select(x => x.Gsmdata.Last())
.ToList();
}

Categories