Child-parent query with composite id on child doing unnecessary multiple queries - c#

I have a very strange problem with this context.
This is the parent object (order heading, IEntity is an empty interface):
public class OrderEntity : IEntity
{
public virtual int prg_ordine { get; set; }
public virtual int num_anno { get; set; }
public virtual int num_doc { get; set; }
public virtual String num_doc_esteso { get; set; }
public virtual DateTime? dat_doc { get; set; }
public virtual String cod_clifor_c { get; set; }
public virtual String rag_soc { get; set; }
public virtual DateTime? dat_evasione { get; set; }
public virtual decimal qta_peso_lordo_kg { get; set; }
public virtual decimal qta_peso_netto_kg { get; set; }
public virtual decimal qta_totale { get; set; }
public virtual String ind_sped { get; set; }
public virtual String ind_sped_div { get; set; }
public virtual String rag_soc_div { get; set; }
public virtual String cod_agente { get; set; }
public virtual String des_agente { get; set; }
public virtual String cod_pag { get; set; }
public virtual String des_pag { get; set; }
public virtual String ind_stato_evas { get; set; }
public virtual int cod_commessa_num { get; set; }
public virtual String des_num_esterno { get; set; }
public virtual ClientEntity client { get; set; }
public virtual ICollection<OrderItemEntity> orderItems { get; set; }
}
This is the child object (order rows):
public class OrderItemEntity : IEntity
{
public virtual int prg_ordine { get; set; }
public virtual int prg_ordine_riga { get; set; }
public virtual String cod_art_completo { get; set; }
public virtual String cod_clifor_c { get; set; }
public virtual String rag_soc { get; set; }
public virtual int num_doc { get; set; }
public virtual String num_doc_esteso { get; set; }
public virtual DateTime? dat_doc { get; set; }
public virtual String cod_art { get; set; }
public virtual String tipo_art { get; set; }
public virtual int prg_art { get; set; }
public virtual String ind_tiporiga { get; set; }
public virtual String cod_um_doc { get; set; }
public virtual String des_articolo_riga { get; set; }
public virtual decimal qta_daevadere { get; set; }
public virtual decimal qta_evasa { get; set; }
public virtual decimal qta_ordine { get; set; }
public virtual DateTime? dat_evasione { get; set; }
public virtual DateTime? dat_evas_riga { get; set; }
public virtual String note { get; set; }
public virtual bool gestisci_pezzatura { get; set; }
public virtual int numero_pezzi { get; set; }
public virtual decimal quantita_pezzo { get; set; }
public virtual string commessa { get; set; }
public virtual int num_riga { get; set; }
public virtual ArticoloDisponibilitaEntity articoloDisponibilita { get; set; }
public virtual OrderEntity order { get; set; }
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
These are the two other objects referred:
public class ClientEntity : IEntity
{
public virtual String cod_clifor { get; set; }
public virtual String des_ragsoc { get; set; }
public virtual String indirizzo { get; set; }
public virtual String codice_e_descrizione
{
get
{
return cod_clifor + " - " + des_ragsoc;
}
}
public virtual ICollection<OrderEntity> orders { get; set; }
}
public class ArticoloDisponibilitaEntity :IEntity
{
public virtual String cod_art_completo { get; set; }
public virtual decimal qta_esistente { get; set; }
public virtual decimal qta_in_distinte_lavorazione { get; set; }
public virtual decimal qta_in_distinte_aperte { get; set; }
public virtual decimal qta_libera_alla_vendita()
{
var ret = qta_esistente - qta_in_distinte_aperte - qta_in_distinte_lavorazione;
if(ret < 0)
ret = 0;
return ret;
}
}
Here are the Fluent nHibernate mapping classes:
public class OrderEntityMap : ClassMap<OrderEntity>
{
public OrderEntityMap()
{
this.Id(x => x.prg_ordine);
this.Map(x => x.num_anno);
this.Map(x => x.num_doc);
this.Map(x => x.num_doc_esteso);
this.Map(x => x.dat_doc);
this.Map(x => x.cod_clifor_c);
this.Map(x => x.rag_soc);
this.Map(x => x.dat_evasione);
this.Map(x => x.qta_peso_lordo_kg);
this.Map(x => x.qta_peso_netto_kg);
this.Map(x => x.qta_totale);
this.Map(x => x.ind_sped);
this.Map(x => x.ind_sped_div);
this.Map(x => x.rag_soc_div);
this.Map(x => x.cod_agente);
this.Map(x => x.des_agente);
this.Map(x => x.cod_pag);
this.Map(x => x.des_pag);
this.Map(x => x.ind_stato_evas);
this.Map(x => x.cod_commessa_num);
this.Map(x => x.des_num_esterno);
References<ClientEntity>(x => x.client, "cod_clifor_c").Not.Nullable();
this.HasMany<OrderItemEntity>(x => x.orderItems).KeyColumn("prg_ordine").Not.LazyLoad().Cascade.All();
this.Table("VW_E_OrdiniTestate");
this.ReadOnly();
}
}
public class OrderItemEntityMap : ClassMap<OrderItemEntity>
{
public OrderItemEntityMap()
{
this.CompositeId()
.KeyProperty(x => x.prg_ordine, "prg_ordine_riga")
.KeyReference(x => x.order, "prg_ordine");
this.Map(x => x.prg_ordine );
this.Map(x => x.prg_ordine_riga );
this.Map(x => x.cod_art_completo );
this.Map(x => x.cod_clifor_c );
this.Map(x => x.rag_soc );
this.Map(x => x.num_doc );
this.Map(x => x.num_doc_esteso );
this.Map(x => x.dat_doc );
this.Map(x => x.cod_art );
this.Map(x => x.tipo_art );
this.Map(x => x.prg_art );
this.Map(x => x.ind_tiporiga );
this.Map(x => x.cod_um_doc );
this.Map(x => x.des_articolo_riga );
this.Map(x => x.qta_daevadere );
this.Map(x => x.qta_evasa );
this.Map(x => x.qta_ordine );
this.Map(x => x.dat_evasione );
this.Map(x => x.dat_evas_riga );
this.Map(x => x.note );
this.Map(x => x.gestisci_pezzatura );
this.Map(x => x.numero_pezzi );
this.Map(x => x.quantita_pezzo);
this.Map(x => x.commessa);
this.Map(x => x.num_riga);
References<ArticoloDisponibilitaEntity>(x => x.articoloDisponibilita, "cod_art_completo").Not.Nullable();
References<OrderEntity>(x => x.order, "prg_ordine").Not.Nullable();
this.Table("VW_E_OrdiniRighe");
this.ReadOnly();
}
}
public class ClientEntityMap : ClassMap<ClientEntity>
{
public ClientEntityMap()
{
this.Table("VW_E_Clienti");
this.Id(x => x.cod_clifor);
this.Map(x=> x.des_ragsoc);
this.Map(x => x.indirizzo);
this.HasMany(x => x.orders).KeyColumn("cod_clifor_c");
}
}
public class ArticoloDisponibilitaEntityMap : ClassMap<ArticoloDisponibilitaEntity>
{
public ArticoloDisponibilitaEntityMap()
{
this.Table("VW_E_Articoli_Disp");
this.Id(x => x.cod_art_completo);
this.Map(x => x.qta_esistente);
this.Map(x => x.qta_in_distinte_aperte);
this.Map(x => x.qta_in_distinte_lavorazione);
this.ReadOnly();
}
}
This query:
return All().FetchMany(x => x.orderItems).Fetch(x => x.client).Where(x => x.cod_clifor_c == filters.clientId).ToList();
Causes this query to be executed:
select orderentit0_.prg_ordine as prg1_11_0_,
orderitems1_.prg_ordine_riga as prg1_12_1_,
orderitems1_.prg_ordine as prg2_12_1_,
cliententi2_.cod_clifor as cod1_3_2_,
orderentit0_.num_anno as num2_11_0_,
orderentit0_.num_doc as num3_11_0_,
orderentit0_.num_doc_esteso as num4_11_0_,
orderentit0_.dat_doc as dat5_11_0_,
orderentit0_.cod_clifor_c as cod6_11_0_,
orderentit0_.rag_soc as rag7_11_0_,
orderentit0_.dat_evasione as dat8_11_0_,
orderentit0_.qta_peso_lordo_kg as qta9_11_0_,
orderentit0_.qta_peso_netto_kg as qta10_11_0_,
orderentit0_.qta_totale as qta11_11_0_,
orderentit0_.ind_sped as ind12_11_0_,
orderentit0_.ind_sped_div as ind13_11_0_,
orderentit0_.rag_soc_div as rag14_11_0_,
orderentit0_.cod_agente as cod15_11_0_,
orderentit0_.des_agente as des16_11_0_,
orderentit0_.cod_pag as cod17_11_0_,
orderentit0_.des_pag as des18_11_0_,
orderentit0_.ind_stato_evas as ind19_11_0_,
orderentit0_.cod_commessa_num as cod20_11_0_,
orderentit0_.des_num_esterno as des21_11_0_,
orderitems1_.cod_art_completo as cod3_12_1_,
orderitems1_.cod_clifor_c as cod4_12_1_,
orderitems1_.rag_soc as rag5_12_1_,
orderitems1_.num_doc as num6_12_1_,
orderitems1_.num_doc_esteso as num7_12_1_,
orderitems1_.dat_doc as dat8_12_1_,
orderitems1_.cod_art as cod9_12_1_,
orderitems1_.tipo_art as tipo10_12_1_,
orderitems1_.prg_art as prg11_12_1_,
orderitems1_.ind_tiporiga as ind12_12_1_,
orderitems1_.cod_um_doc as cod13_12_1_,
orderitems1_.des_articolo_riga as des14_12_1_,
orderitems1_.qta_daevadere as qta15_12_1_,
orderitems1_.qta_evasa as qta16_12_1_,
orderitems1_.qta_ordine as qta17_12_1_,
orderitems1_.dat_evasione as dat18_12_1_,
orderitems1_.dat_evas_riga as dat19_12_1_,
orderitems1_.note as note12_1_,
orderitems1_.gestisci_pezzatura as gestisci21_12_1_,
orderitems1_.numero_pezzi as numero22_12_1_,
orderitems1_.quantita_pezzo as quantita23_12_1_,
orderitems1_.commessa as commessa12_1_,
orderitems1_.num_riga as num25_12_1_,
orderitems1_.prg_ordine as prg2_0__,
orderitems1_.prg_ordine_riga as prg1_0__,
cliententi2_.des_ragsoc as des2_3_2_,
cliententi2_.indirizzo as indirizzo3_2_
from VW_E_OrdiniTestate orderentit0_
left outer join VW_E_OrdiniRighe orderitems1_
on orderentit0_.prg_ordine = orderitems1_.prg_ordine
left outer join VW_E_Clienti cliententi2_
on orderentit0_.cod_clifor_c = cliententi2_.cod_clifor
where orderentit0_.cod_clifor_c = '000030' /* #p0 */
which is perfectly fine.
The problem is that, after the above query, one query PER ORDER ROW is then executed, like this:
SELECT orderiteme0_.prg_ordine_riga as prg1_12_0_,
orderiteme0_.prg_ordine as prg2_12_0_,
orderiteme0_.cod_art_completo as cod3_12_0_,
orderiteme0_.cod_clifor_c as cod4_12_0_,
orderiteme0_.rag_soc as rag5_12_0_,
orderiteme0_.num_doc as num6_12_0_,
orderiteme0_.num_doc_esteso as num7_12_0_,
orderiteme0_.dat_doc as dat8_12_0_,
orderiteme0_.cod_art as cod9_12_0_,
orderiteme0_.tipo_art as tipo10_12_0_,
orderiteme0_.prg_art as prg11_12_0_,
orderiteme0_.ind_tiporiga as ind12_12_0_,
orderiteme0_.cod_um_doc as cod13_12_0_,
orderiteme0_.des_articolo_riga as des14_12_0_,
orderiteme0_.qta_daevadere as qta15_12_0_,
orderiteme0_.qta_evasa as qta16_12_0_,
orderiteme0_.qta_ordine as qta17_12_0_,
orderiteme0_.dat_evasione as dat18_12_0_,
orderiteme0_.dat_evas_riga as dat19_12_0_,
orderiteme0_.note as note12_0_,
orderiteme0_.gestisci_pezzatura as gestisci21_12_0_,
orderiteme0_.numero_pezzi as numero22_12_0_,
orderiteme0_.quantita_pezzo as quantita23_12_0_,
orderiteme0_.commessa as commessa12_0_,
orderiteme0_.num_riga as num25_12_0_
FROM VW_E_OrdiniRighe orderiteme0_
WHERE orderiteme0_.prg_ordine_riga = 1 /* #p0 */
and orderiteme0_.prg_ordine = 22 /* #p1 */
This is unexpected and unwanted; I suspect something wrong in the mappings, but it seems everything good to me.
Any hint on why this happens and how to avoid it?
Thanks,
Mario

I think your problem is with the implementation of the GetHashCode method in the child entity, with Nhibernate when you have a composite id you have to tell to Nh how to reconize the entities.
Try to implement those two methods:
public override bool Equals(object obj)
{
OrderItemEntity objfrom = (OrderItemEntity)obj;
return ((this.prg_ordine == objfrom.prg_ordine) && (this.prg_ordine_riga == objfrom.prg_ordine_riga));
}
public override int GetHashCode()
{
unchecked
{
return ((this.prg_ordine * 100000) + this.prg_ordine_riga);
}
Bye
Marco

Related

GetAllIncluding With Optional Relationships ABP

I have an entity with some optional relationships and I'm doing a GetAllIncluding(someProperties) but the navigation properties keeps in null when the GetAll is done.
All relation in the include (Cliente, ClienteFuturo) keeps in null, and always almost one of them has a value on ClienteId or ClienteFuturoId
Here is my GetAll Method:
public override Task<PagedResultDto<SolicitudPrestamoDto>> GetAll(PagedAndSortedRequest input)
{
var lista = new List<SolicitudPrestamo>();
var query = Repository.GetAllIncluding(x => x.ClienteFuturo, x => x.Cliente);
query = CreateFilteredQuery(input);
query = ApplySorting(query, input);
query = FilterHelper<SolicitudPrestamo>.FilerByProperties(input.FilterProperties, query);
lista = query
.Skip(input.SkipCount)
.Take(input.MaxResultCount)
.ToList();
var result = new PagedResultDto<SolicitudPrestamoDto>(query.Count(), ObjectMapper.Map<List<SolicitudPrestamoDto>>(lista));
return Task.FromResult(result);
}
Here is the entity relation configuration:
entidad.HasOne(e => e.Cosolicitante)
.WithMany()
.HasForeignKey(e => e.CosolicitanteId)
.HasConstraintName("ForeignKey_SolicitudPrestamo_Cosolicitante")
.OnDelete(DeleteBehavior.Restrict);
entidad.HasOne(e => e.Cliente)
.WithMany()
.HasForeignKey(e => e.ClienteId)
.HasConstraintName("ForeignKey_SolicitudPrestamo_Cliente")
.OnDelete(DeleteBehavior.Restrict);
entidad.HasOne(e => e.CosolicitanteCliente)
.WithMany()
.HasForeignKey(e => e.CosolicitanteClienteId)
.HasConstraintName("ForeignKey_SolicitudPrestamo_CosolicitanteCliente")
.OnDelete(DeleteBehavior.Restrict);
entidad.HasOne(e => e.ClienteFuturo)
.WithMany()
.HasForeignKey(e => e.ClienteFuturoId)
.HasConstraintName("ForeignKey_SolicitudPrestamo_ClienteFuturo")
.OnDelete(DeleteBehavior.Restrict);
Here is my entity:
public class SolicitudPrestamo : AuditedEntity<int>
{
public string Identificador { get; set; }
public int CantidadCuotas { get; set; }
public double Monto { get; set; }
public string FormaPago { get; set; }
public DateTime Fecha { get; set; }
public string Proposito { get; set; }
public string Referencia { get; set; }
public EstadoSolicitud Estado { get; set; }
public int SucursalId { get; set; }
public virtual Sucursal Sucursal { get; set; }
public int? ClienteId { get; set; }
public virtual Cliente Cliente { get; set; }
public int? CosolicitanteClienteId { get; set; }
public virtual Cliente CosolicitanteCliente { get; set; }
public int? ClienteFuturoId { get; set; }
public virtual ClienteFuturo ClienteFuturo { get; set; }
public int ClasificacionPrestamoId { get; set; }
public virtual ClasificacionPrestamo ClasificacionPrestamo { get; set; }
public int? OficialNegocioId { get; set; }
public virtual OficialNegocio OficialNegocio { get; set; }
public int? CobradorPrestamoId { get; set; }
public virtual CobradorPrestamo CobradorPrestamo { get; set; }
public int? CosolicitanteId { get; set; }
public virtual ClienteFuturo Cosolicitante { get; set; }
public IEnumerable<GarantiaPrestamoSolicitud> ListaGarantiaPrestamo { get; set; }
public IEnumerable<ReferenciaPrestamo> ListaReferencias { get; set; }
public List<GarantiaPrestamo> ListaGarantias { get; set; }
}
Sorry for my English.
protected override IQueryable<SolicitudPrestamo> CreateFilteredQuery(PagedAndSortedRequest input)
{
return Repository.GetAll().
WhereIf(!input.Filter.IsNullOrWhiteSpace(), x =>
x.Identificador.StartsWith(input.Filter, StringComparison.CurrentCultureIgnoreCase) ||
x.FormaPago.StartsWith(input.Filter, StringComparison.CurrentCultureIgnoreCase) ||
x.Proposito.StartsWith(input.Filter, StringComparison.CurrentCultureIgnoreCase) ||
x.Referencia.StartsWith(input.Filter, StringComparison.CurrentCultureIgnoreCase)
);
}
Thanks illia-popov the problem is that in the CreatedFilteredQuery Method I forget to do the GetAllIncluding
Thanks for help.!

Violation of PRIMARY KEY constraint, even though im not adding or modyfying anything in the context

My program is parsing an xml file and adding orders from this file to the mssql database. Before he adds those orders to database he analyses them if there are any duplicates that need to be dealt with.
foreach (var newOrderXml in newOrdersList)
{
var dupesInDb = _context.OrdersXml.Include(o=>o.OrderXmlItems)
.Where(o => o.OrX_ORDERNR.Contains(newOrderXml.OrX_ORDERNR))
.ToList();
_context.SaveChanges();
}
Program loops through all of the new orders in newOrderList and gets the list of duplicates with linq query. If there are 0 duplicates and nothing gets returned, everything works fine, but if a single duplicate is returned then SaveChanges method will throw an exception "Violation of PRIMARY KEY constraint PK_dbo.SewingCardBundles, Cannot insert duplicate key in object 'dbo.SewingCardBundles'. The duplicate key value is (1).", even though im not adding or modyfying anything in the context. I dont really know what is happening, all im doing is getting, im not changing anything, im not creating new objects. This exception happens exactly at this spot, if i try to save changes before this linq query then nothing bad happens but if i try it after this linq query i get the exceptions. So where does those changes to context come from?
Here are my models:
public class OrderXml
{
public OrderXml()
{
OrderXmlItems = new List<OrderXmlItem>();
}
public int OrX_Id { get; set; }
public string OrX_ORDERNR { get; set; }
public string OrX_REFERGB { get; set; }
public int? OrX_CUSTOMERNUM { get; set; }
public string OrX_DNAME { get; set; }
public string OrX_DADR { get; set; }
public string OrX_DPCODE { get; set; }
public string OrX_POSTALCODE { get; set; }
public string OrX_COUNTRY { get; set; }
public string OrX_PHONE { get; set; }
public string OrX_EMAIL { get; set; }
public int? OrX_LANG { get; set; }
public int? OrX_CUSTGRP { get; set; }
public int? OrX_QUALITCON { get; set; }
public string OrX_SHIPVIA { get; set; }
public string OrX_DATE1 { get; set; }
public string OrX_DATE2 { get; set; }
public string OrX_DELIVGB { get; set; }
public string OrX_SORT { get; set; }
public int? OrX_CURLAB { get; set; }
public List<OrderXmlItem> OrderXmlItems { get; set; }
public Adress Adress { get; set; }
}
public OrderXmlItem()
{
SewingCardBundle = new SewingCardBundle();
}
public int OxI_Id { get; set; }
public int? OxI_PRODUCT { get; set; }
public int? OxI_ORDERLINE { get; set; }
public int? OxI_QUANTITY { get; set; }
public int? OxI_TYPE { get; set; }
public string OxI_TPFABNR { get; set; }
public string OxI_TPFABDEF { get; set; }
public string OxI_TPFABNAME { get; set; }
public int? OxI_CURDIR { get; set; }
public int? OxI_CURWIDTH { get; set; }
public int? OxI_CURHEIGHT { get; set; }
public int? OxI_WORKMETH { get; set; }
public int? OxI_FOLDTYPE { get; set; }
public decimal? OxI_FOLDFACT { get; set; }
public int? OxI_CURBAND { get; set; }
public int? OxI_CURHEAD { get; set; }
public int? OxI_CURBOTSEAM { get; set; }
public int? OxI_PACKWLEFT { get; set; }
public int? OxI_PACKWRIGHT { get; set; }
public decimal? OxI_NRSTROL { get; set; }
public decimal? OxI_NRSTROR { get; set; }
public int? OxI_LINTYP { get; set; }
public string OxI_LINCOL { get; set; }
public int? OxI_EMBSORT { get; set; }
public int? OxI_EXTRA { get; set; }
public int? OxI_PRODUCE { get; set; }
public int? OxI_PACKSORT { get; set; }
public int? OxI_CURMODEL { get; set; }
public string OxI_BARCODE { get; set; }
public string OxI_EXTRAINF { get; set; }
public int? OxI_RAILTYP { get; set; }
public int? OxI_RAILCONT { get; set; }
public int? OxI_RAILCONTSIDE { get; set; }
public decimal? OxI_FABSTROTOT { get; set; }
public decimal? OxI_FABSTROLEFT { get; set; }
public decimal? OxI_FABSTRORIGHT { get; set; }
public int? OxI_FABUNDSIZ { get; set; }
public int? OxI_FABTOTSIZ { get; set; }
public int? OxI_LINSTROTOT { get; set; }
public int? OxI_LINUNDSIZ { get; set; }
public int? OxI_LINTOTSIZ { get; set; }
public decimal? OxI_FABWIDTH { get; set; }
public int? OxI_CHILDSFT { get; set; }
public int? OxI_FOLDSORT { get; set; }
public int? OxI_EMBLENGTH { get; set; }
public int? OxI_PACKMETH { get; set; }
public int OrderXmlId { get; set; }
public OrderXml OrderXml { get; set; }
public SewingCardBundle SewingCardBundle { get; set; }
}
public class SewingCardBundle
{
public SewingCardBundle()
{
FlamanSewingCards = new List<FlamandzkaSewingCard>();
FlamandzkaBrytaSewingCards = new List<FlamandzkaBrytaSewingCard>();
OczkaSewingCards = new List<OczkaSewingCard>();
OczkaBrytaSewingCards = new List<OczkaBrytaSewingCard>();
WellenbandSewingCards = new List<WellenbandSewingCard>();
WellenbandBrytaSewingCards = new List<WellenbandBrytaSewingCard>();
PodwiazkaSewingCards = new List<PodwiazkaSewingCard>();
TunelSewingCards = new List<TunelSewingCard>();
}
public int SwC_Id { get; set; }
public OrderXmlItem OrderXmlItem { get; set; }
public List<FlamandzkaSewingCard> FlamanSewingCards { get; set; }
public List<FlamandzkaBrytaSewingCard> FlamandzkaBrytaSewingCards { get; set; }
public List<OczkaSewingCard> OczkaSewingCards { get; set; }
public List<OczkaBrytaSewingCard> OczkaBrytaSewingCards { get; set; }
public List<WellenbandSewingCard> WellenbandSewingCards { get; set; }
public List<WellenbandBrytaSewingCard> WellenbandBrytaSewingCards { get; set; }
public List<PodwiazkaSewingCard> PodwiazkaSewingCards { get; set; }
public List<TunelSewingCard> TunelSewingCards { get; set; }
}
and my Fluent API configurations for those models:
public class OrderXmlConfiguration : EntityTypeConfiguration<OrderXml>
{
public OrderXmlConfiguration()
{
HasKey(o => o.OrX_Id);
Property(o => o.OrX_ORDERNR).IsRequired();
Property(o => o.OrX_REFERGB).IsRequired();
Property(o => o.OrX_CUSTOMERNUM).IsRequired();
Property(o => o.OrX_DNAME).IsRequired();
Property(o => o.OrX_DPCODE).IsRequired();
Property(o => o.OrX_POSTALCODE).IsRequired();
Property(o => o.OrX_COUNTRY).IsRequired();
Property(o => o.OrX_LANG).IsRequired();
Property(o => o.OrX_CUSTGRP).IsRequired();
Property(o => o.OrX_SHIPVIA).IsRequired();
Property(o => o.OrX_CURLAB).IsRequired();
HasMany(i => i.OrderXmlItems)
.WithRequired(o => o.OrderXml)
.HasForeignKey(o => o.OrderXmlId)
.WillCascadeOnDelete(true);
}
}
public class OrderXmlItemConfiguration : EntityTypeConfiguration<OrderXmlItem>
{
public OrderXmlItemConfiguration()
{
HasKey(o => o.OxI_Id);
Property(p => p.OxI_Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(p => p.OxI_PRODUCT).IsRequired();
Property(p => p.OxI_ORDERLINE).IsRequired();
Property(p => p.OxI_QUANTITY).IsRequired();
Property(p => p.OxI_TYPE).IsRequired();
Property(p => p.OxI_CURDIR).IsRequired();
Property(p => p.OxI_CURWIDTH).IsRequired();
Property(p => p.OxI_CURHEIGHT).IsRequired();
Property(p => p.OxI_WORKMETH).IsRequired();
Property(p => p.OxI_FOLDTYPE).IsRequired();
Property(p => p.OxI_FOLDFACT).IsRequired();
Property(p => p.OxI_PACKWLEFT).IsRequired();
Property(p => p.OxI_PACKWRIGHT).IsRequired();
Property(p => p.OxI_BARCODE).IsRequired();
HasRequired(i => i.SewingCardBundle)
.WithRequiredPrincipal( s=> s.OrderXmlItem)
.WillCascadeOnDelete(true);
}
}
public class SewingCardBundleConfiguration : EntityTypeConfiguration<SewingCardBundle>
{
public SewingCardBundleConfiguration()
{
HasKey(s => s.SwC_Id);
HasMany(s=>s.FlamanSewingCards)
.WithRequired(c=>c.SewingCardBundle)
.WillCascadeOnDelete(true);
HasMany(s => s.FlamandzkaBrytaSewingCards)
.WithRequired(c => c.SewingCardBundle)
.WillCascadeOnDelete(true);
HasMany(s => s.OczkaBrytaSewingCards)
.WithRequired(c => c.SewingCardBundle)
.WillCascadeOnDelete(true);
HasMany(s => s.OczkaSewingCards)
.WithRequired(c => c.SewingCardBundle)
.WillCascadeOnDelete(true);
HasMany(s => s.WellenbandSewingCards)
.WithRequired(c => c.SewingCardBundle)
.WillCascadeOnDelete(true);
HasMany(s => s.WellenbandBrytaSewingCards)
.WithRequired(c => c.SewingCardBundle)
.WillCascadeOnDelete(true);
HasMany(s => s.TunelSewingCards)
.WithRequired(c => c.SewingCardBundle)
.WillCascadeOnDelete(true);
HasMany(s => s.PodwiazkaSewingCards)
.WithRequired(c => c.SewingCardBundle)
.WillCascadeOnDelete(true);
}
}
I'm not sure why you are calling SaveChanges in the first place (it is not needed), but once you get your data from database, context will track them (i.e. have them cached).
Since, you haven't specified AsNoTracking in your query, SaveChanges method will try to save entities which are being tracked which will lead to your "primary key violation" exception.
To circumvent the issue, you can just specify AsNoTracking:
var dupesInDb = _context
.OrdersXml.Include(o=>o.OrderXmlItems)
.Where(o => o.OrX_ORDERNR.Contains(newOrderXml.OrX_ORDERNR))
.AsNoTracking()
.ToList();

Mapping to nested value Automapper

I'm struggling to map 2 objects. Basically have Product which is my EF model, and I'm mapping this to ProductDto, which has FileDto.
I'd like to map Product.FileName to ProductDto.File.Internal name, how to do this?
Classes below.
public class Product : BaseEntity<long>
{
[MaxLength(100)]
public string Name { get; set; }
[MaxLength(100)]
public string Barcode { get; set; }
public int ShelfLife { get; set; }
public int Weight { get; set; }
public bool HasAllergens { get; set; }
[MaxLength(100)]
public string FileName { get; set; }
[ForeignKey("Id")]
public int CustomerId { get; set; }
public virtual ICollection<ProductIngredient> ProductIngredient { get; set; }
public virtual ICollection<Nutrition> Nutritions { get; set; }
public virtual ICollection<ProductComposition> Composition { get; set; }
public virtual IList<ProductionProcess> ProductionProcess { get; set; }
}
public class ProductDto
{
public long Id { get; set; }
public DateTime CretedOn { get; set; }
public DateTime UpdatedOn { get; set; }
public string Name { get; set; }
public string Barcode { get; set; }
public int ShelfLife { get; set; }
public int Weight { get; set; }
public bool HasAllergens { get; set; }
public int CustomerId { get; set; }
public FileDto File { get; set; }
public IList<IngredientDto> Ingredients { get; set; }
public IList<NutritionDto> Nutritions { get; set; }
public IList<ProductCompositionDto> Composition { get; set; }
public IList<ProductionProcessDto> ProductionProcess { get; set; }
}
public class ProductionProcessDto
{
public string Key { get; set; }
public string Value { get; set; }
public FileDto File { get; set; }
}
public class NutritionDto
{
public string Key { get; set; }
public string Value { get; set; }
}
public class ProductCompositionDto
{
public string Key { get; set; }
public string Value { get; set; }
}
File Dto:
public class FileDto
{
public string Base64EncodedFile { get; set; }
public string OriginalName { get; set; }
public string InternalName { get; set; }
public string Type { get; set; }
}
Automapper so far:
//Product
CreateMap<Nutrition, NutritionDto>().ReverseMap();
CreateMap<ProductComposition, ProductCompositionDto>().ReverseMap();
CreateMap<ProductionProcessDto, ProductionProcess>()
.ForMember(dest => dest.FileInternalName, opt => opt.MapFrom(src => src.File.InternalName))
.ForMember(dest => dest.FileOriginalName, opt => opt.MapFrom(src => src.File.OriginalName))
.ReverseMap();
CreateMap<Product, ProductDto>()
.ForMember(d => d.File, o => o.MapFrom(s => Mapper.Map<Product, FileDto>(s)))
.ForMember(d => d.Nutritions, o => o.MapFrom(s => s.Nutritions))
.ForMember(d => d.Composition, o => o.MapFrom(s => s.Composition))
.ForMember(d => d.ProductionProcess, o => o.MapFrom(s => s.ProductionProcess))
.ForMember(d => d.Ingredients, o => o.MapFrom(s => s.ProductIngredient.Select(pi => pi.Ingredients)))
.ReverseMap();
CreateMap<ProductDto, Product>()
.ForMember(d => d.FileName, o => o.MapFrom(s => s.File.InternalName))
.ReverseMap();
I am able to map from ProductDto (on data post) to Product but not other way around, all help much appreciated
Thanks
This code solved my issue:
.ForMember(d => d.File, o => o.MapFrom(model => new FileDto { InternalName = model.FileName }))
Applied to:
CreateMap<Product, ProductDto>()

Working with Embeddable in FluentNHibernate?

I'm looking for any how to or documentation about use of Embeddable with FluentNHibernate exactly with in the Hibernate. Does has any way to works with Embeddable in FluentNHibernate, if not has what's the best way to simulate this ?
Finally I found some solution. It's very simple like Embeddable of JPA/Hibernate.
Found here: https://github.com/jagregory/fluent-nhibernate/wiki/Fluent-mapping#components
Then I did.
public class Cliente {
public virtual long id { set; get; }
public virtual long codigo { set; get; }
public virtual String nome { set; get; }
public virtual String sexo { set; get; }
public virtual String cpf { set; get; }
public virtual String rg { set; get; }
public virtual DateTime dtNascimento { set; get; }
public virtual Endereco endereco { set; get; } //Embeddable
public Cliente() { }
}
public class Endereco {
public String endereco;
public String numero;
public String bairro;
public String complemento;
public String cidade;
public String cep;
public EstadosBrasil uf;
public Endereco() {
}
}
Mapping
public class ClienteMap : ClassMap<Cliente> {
public ClienteMap() {
Table("CLIENTE");
Id(c => c.id).GeneratedBy.Native();
Map(c => c.codigo);
Map(c => c.nome);
Map(c => c.sexo).Length(2);
Map(c => c.cpf);
Map(c => c.rg);
Map(c => c.dtNascimento).CustomType<DateTime>();
//embeddable
Component(c => c.endereco, e => {
e.Map(c => c.endereco);
e.Map(c => c.numero).CustomType<int>();
e.Map(c => c.bairro);
e.Map(c => c.complemento);
e.Map(c => c.cidade);
e.Map(c => c.cep);
e.Map(c => c.uf).CustomType<GenericEnumMapper<EstadosBrasil>>();
});
}
}

EF 5, Fluent API : invalid column name "Source_ID"

Good morning
I Get invalid column name "Source_ID". my models are :
product:
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public Nullable<decimal> PreviousPrice { get; set; }
public string Url { get; set; }
public int SourceID { get; set; }
public int SectionID { get; set; }
public int CategoryID { get; set; }
public Nullable<int> BrandID { get; set; }
public string PublisherProductID { get; set; }
public string PictureFilename { get; set; }
public bool Deleted { get; set; }
public Nullable<int> Score { get; set; }
public string EAN { get; set; }
public string ExtraAttributes { get; set; }
public DateTime LastUpdateDate { get; set; }
public DateTime InsertDate { get; set; }
public string Keywords { get; set; }
public virtual ProductPicture ProductPicture { get; set; }
public virtual Brand Brand { get; set; }
public virtual Source Source { get; set; }
public virtual Category Category { get; set; }
public virtual Section Section { get; set; }
public virtual ICollection<ProductComment> Comments { get; set; }
public virtual ICollection<Like> Likes { get; set; }
public virtual ICollection<Aside> Asides { get; set; }
public virtual ICollection<Wish> Wishlists { get; set; }
public virtual ICollection<UserRecommendation> UserRecommendations { get; set; }
public virtual ICollection<ProductColor> ProductColors { get; set; }
public virtual ICollection<ProductView> ProductViews { get; set; }
public virtual ICollection<PointLog> PointLogs { get; set; }
public virtual ICollection<InvitationLog> InvitationLogs { get; set; }
public virtual ICollection<FeedItem> FeedItems { get; set; }
public virtual ICollection<Sale> Sales { get; set; }
public virtual ICollection<ListProduct> ListProducts { get; set; }
public virtual ICollection<BonusMalus> BonusMalus { get; set; }
public virtual ICollection<ProductHunter> Hunters { get; set; }
Product Mapping :
HasKey(e => e.ID);
Property(e => e.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(e => e.Name).IsRequired().HasColumnType("VARCHAR").HasMaxLength(200);
Property(e => e.Description).HasColumnType("VARCHAR").HasMaxLength(4000);
Property(e => e.Price).IsRequired().HasColumnType("Money");
Property(e => e.PreviousPrice).IsOptional().HasColumnType("Money");
Property(e => e.ExtraAttributes).HasColumnType("VARCHAR").IsOptional().HasMaxLength(1000);
Property(e => e.Url).IsRequired().HasColumnType("VARCHAR").HasMaxLength(2048);
Property(e => e.LastUpdateDate).IsOptional();
Property(e => e.InsertDate).IsOptional();
Property(e => e.PictureFilename).HasColumnType("VARCHAR").HasMaxLength(200);
Property(e => e.Deleted).IsRequired();
Property(e => e.EAN).IsOptional().HasColumnType("VARCHAR").HasMaxLength(18);
Property(e => e.PublisherProductID).IsRequired().HasColumnType("VARCHAR").HasMaxLength(100);
Property(e => e.BrandID).IsOptional();
Property(e => e.SourceID).IsRequired();
Property(e => e.Keywords).HasColumnType("VARCHAR").HasMaxLength(500);
ToTable("Products");
HasOptional(t => t.Brand).WithMany(t => t.Products).HasForeignKey(d => d.BrandID);
HasRequired(e => e.Source).WithMany(s => s.Products).HasForeignKey(e => e.SourceID);
HasRequired(e => e.Category).WithMany(c => c.Products).HasForeignKey(e => e.CategoryID);
HasRequired(t => t.Section).WithMany(t => t.Products).HasForeignKey(d => d.SectionID);
Source :
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Products { get; set; }
public virtual ICollection<SourceCategory> SourceCategories { get; set; }
public virtual ICollection<SourceCategoryRule> SourceCategoryRules { get; set; }
public virtual ICollection<WishlistGame> WishlistGames { get; set; }
public virtual ICollection<SourceWebsiteCommission> Commissions { get; set; }
public virtual ICollection<Sale> Sales { get; set; }
Source Mapping :
HasKey(e => e.ID);
Property(e => e.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
Property(e => e.Name).IsRequired().HasColumnType("VARCHAR").HasMaxLength(50);
ToTable("Sources");
The tables Products & Sources are already created. when i run my solution i got this problem (invalid column name Source_ID). maybe it is an error in my mapping. Anyone have a solution ?

Categories