229 messaggi dal 20 novembre 2014
Ecco che c'è qualcosa che non va, lascia stare il fatto che potrei aggirare l'ostacolo in altri modi ma voglio capire qual è il problema.
Dunque ho creato un'altra relazione identica a quella che mi hai fatto tu, quindi: ho la tabella OperatoriAbilitatiInterventi che ha una relazione uno a molti con la tabella Tipo_TipoInterventi per cui per ogni operatoreabilitato (presente nella tabella OperatoriAbilitatiInterventi) io posso avere uno o più tipi di Intervento presenti nella tabella Tipo_TipoInterventi l'unica differenza rispetto a prima è che la chiave esterna sta a sx sulla tabella OperatoriAbilitatiInterventi e si chiama IdTipoTipoInterventi che è quella che non riesco a matchare con la mappatura.

Modello OperatoriAbilitatiInterventi:
public class OperatoriAbilitatiInterventi
{
//Faccio l'hashset per la mappatura con OperatoriAbilitatiInterventi->TipoTipoInterventi
public OperatoriAbilitatiInterventi()
{
TipoTipoIntervento = new HashSet<Tipo_TipoInterventi>();
}
public virtual ICollection<Tipo_TipoInterventi> TipoTipoIntervento { get; set; }

[Key]
public int ID { get; set; }
[Display(Name = "Operatore")]
public int IdOperatore { get; set; }
[Display(Name = "Intervento")]
public int IdTipoTipoInterventi { get; set; }

public virtual Personale Personale { get; set; }

public string Utente { get; set; }
public DateTime Modifica { get; set; }

[Display(Name = "Attivo")]
public Boolean Attivo { get; set; }

}

Modello Tipo_TipoInterventi
public class Tipo_TipoInterventi
{
[Key]
public int ID { get; set; }
[StringLength(1000)]
[Display(Name = "Descrizione")]
public string Descrizione { get; set; }
[Display(Name = "Attivo")]
public Boolean Attivo { get; set; }

public virtual OperatoriAbilitatiInterventi OperatoreAbilitatoIntervento { get; set; }

}

faccio la mappatura:
modelBuilder.Entity<OperatoriAbilitatiInterventi>()
.HasMany(t => t.TipoTipoIntervento)
.WithRequired(tti => tti.OperatoreAbilitatoIntervento)
.HasForeignKey(tti => tti.OperatoreAbilitatoIntervento.IdTipoTipoInterventi);
//.Map(m =>
//{
// m.ToTable("Tipo_TipoInterventi");
// m.MapKey("IdTipoTipoInterventi");
//});

inutile dire che facendo .HasForeignKey(tti => tti.IdTipoTipoInterventi) non lo trova per cui ho fatto un po di prove ma non riesco a mappare la chiave.
Altra domanda stupida ma non trovo soluzione: nella documentazione ufficiale che mi hai mandato msdn dov'è la relazione uno a molti?
11.886 messaggi dal 09 febbraio 2002
Contributi

ma voglio capire qual è il problema.

Bravo, a me mappare le relazioni con Entity Framework Code First ha insegnato a capire meglio le relazioni perché l'interfaccia fluente ti indirizza verso l'uso corretto delle foreign key (per esempio).


inutile dire che facendo .HasForeignKey(tti => tti.IdTipoTipoInterventi) non lo trova

E' normale che sia così. E' un chiaro indizio che c'è qualcosa che non va nel modo in cui hai interpretato la relazione. Entity Framework ti aiuta così a ragionare su questo fatto. Andiamo a vedere perché...


la chiave esterna sta a sx sulla tabella OperatoriAbilitatiInterventi e si chiama IdTipoTipoInterventi

E' questo il problema: non è possibile che si trovi a sinistra. Nelle relazioni "uno a molti" deve trovarsi per forza a destra, nella tabella Tipo_TipoInterventi.
Guarda questo diagramma che illustra una relazione 1 a molti.
http://en.tekstenuitleg.net/media/22949/one-to-many_relationship.png
La chiave esterna (cutomer_id) si trova a destra e questo rende possibile avere molti record Order per ogni Customer. Infatti, se vari Order hanno lo stesso customer_id, ecco che abbiamo legato quel Customer a più Order.

Se la tua chiave esterna si trova a sinistra e dici che c'è una relazione "a molti" sull'altra tabella, allora probabilmente stai coinvolgendo più di due tabelle. Qui un diagramma E/R aiuterebbe a capire ma non so se vuoi divulgare la struttura del tuo DB.

Potrebbe essere che la tua chiave esterna, quella che hai a sinistra, serva per una relazione uno-a-molti con un'altra tabella intermediaria che poi, a sua volta, ha una seconda relazione uno a molti con OperatoriAbilitatiInterventi.

Se questo sia corretto non lo so. A volte si fa quando la relazione molti-a-molti non ti è sufficiente perché vuoi anche "annotare la relazione" (frase che mi sono inventato or ora) con delle proprietà.

ciao,
Moreno

PS. In questo post ho usato la parola "sinistra" per indicare l'entità principale e "destra" per indicare l'entità dipendente.
Esempi di mapping uno-a-molti li trovi in quell'articolo, nei paragrafi più in basso. Li riconosci perché il mapping è fatto con i metodi HasMany/WithOptional o HasMany/WithRequired, a seconda che la foreign key sia nullable o meno.
Modificato da BrightSoul il 21 luglio 2016 08.26 -

Enjoy learning and just keep making
229 messaggi dal 20 novembre 2014
Sei un grande!
Grazie mille, risposta impeccabile, mi hai dato conferma che devo cambiare qualcosina in tabella :)
229 messaggi dal 20 novembre 2014
Ciao Moreno,
purtroppo l'incubo non è ancora finito.
Questa mattina ho cercato di fare la mappatura per quanto riguarda il Tipo_TipoInterventi, e come da te preannunciato in tempi non sospetti facendo il data model mi sono reso conto che non avevo ben capito la relazione ossia: la relazione fra OperatoriAbilitatiInterventi e Tipo_TipoInterventi non è uno a molti ma uno ad uno per cui sono riuscito a mappare ed è andato al posto. Ora il problema dove sta, sta nel fatto che quando faccio le mappature col model builder mi dice che ha bisogno di fare la migrazione perchè sono state effettuate modifiche al db. La stessa cosa mi era stata segnalata con la prima mappatura che mi avevi fatto tu, allora io essendo che mi dava errore incomprensibile nell'aggiornamento smanettando avevo ingannato code first commentando la migrazione e tutto ok, parte con la index ma appena clicco su modifica va in errore.
Ho rigenerato la tabella e appena fatta la mappatura col model builder ritorna sempre lo stesso problema mi dice di fare la migrazione ma va in errore, questo è l'errore:

Il parametro @objname è ambiguo oppure il parametro @objtype specificato (COLUMN) non è corretto.

le ho provate tutte, ho cancellato tutti i record della tabella, ho cancellato la tabella e l'ho fatta rigenerare... niente non capisco come risolvere... hai idea del perchè mi succede questa cosa?

ah, la migrazione incriminata è questa:
public partial class OperatoriAbilitatiInterventi4 : DbMigration
{
public override void Up()
{
DropForeignKey("dbo.OperatoriAbilitatiInterventi", "Personale_ID", "dbo.Personale");
DropIndex("dbo.OperatoriAbilitatiInterventi", new[] { "Personale_ID" });
DropColumn("dbo.OperatoriAbilitatiInterventi", "IdOperatore");
RenameColumn(table: "dbo.OperatoriAbilitatiInterventi", name: "Personale_ID", newName: "IdOperatore");
AlterColumn("dbo.OperatoriAbilitatiInterventi", "IdOperatore", c => c.Int(nullable: false));
CreateIndex("dbo.OperatoriAbilitatiInterventi", "IdOperatore");
AddForeignKey("dbo.OperatoriAbilitatiInterventi", "IdOperatore", "dbo.Personale", "ID", cascadeDelete: true);
}

public override void Down()
{
DropForeignKey("dbo.OperatoriAbilitatiInterventi", "IdOperatore", "dbo.Personale");
DropIndex("dbo.OperatoriAbilitatiInterventi", new[] { "IdOperatore" });
AlterColumn("dbo.OperatoriAbilitatiInterventi", "IdOperatore", c => c.Int());
RenameColumn(table: "dbo.OperatoriAbilitatiInterventi", name: "IdOperatore", newName: "Personale_ID");
AddColumn("dbo.OperatoriAbilitatiInterventi", "IdOperatore", c => c.Int(nullable: false));
CreateIndex("dbo.OperatoriAbilitatiInterventi", "Personale_ID");
AddForeignKey("dbo.OperatoriAbilitatiInterventi", "Personale_ID", "dbo.Personale", "ID");
}
}

Spero che sai darmi una dritta perchè ci sto ammattendo
Grazie
229 messaggi dal 20 novembre 2014
Lascio la risposta per qualcuno che si ritrova nella mia stessa situazione: il problema si verifica per la chiave esterna che va in join, io dato l'inferno che avevo combinato purtroppo ho dovuto far cancellare le tabelle e ricrearle però è andato tutto al posto. Certo mi rimane da capire come fare... non posso ogni volta che inserisco una proprietà di navigazione cancellare le tabelle e rifarle.
Grazie Moreno per il supporto
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,


non posso ogni volta che inserisco una proprietà di navigazione cancellare le tabelle e rifarle

No, non bisogna cancellare nulla. Non vorrei che stessi mischiando due approcci.
  • Se ti piace partire dal database e costruirlo a mano, allora non devi far generare il database da EF code first con le migrations o con altro tipo di initializer. In questo caso, disabilita l'initializer e fai in modo che il tuo mapping rifletta lo schema che hai già costruito.
  • Se ti piace partire dal modello, allora lascia che sia EF a costruire il database (io uso questo approccio). Man mano che il tuo modello si evolve, crea delle migrations che serviranno al comando Update-Database per modificare lo schema di conseguenza.


Quale dei due è il tuo caso?

ciao,
Moreno

Enjoy learning and just keep making
229 messaggi dal 20 novembre 2014
Ciao Moreno, il mio approccio è il secondo che ritengo essere molto comodo ma dopo le mappature si era bloccato dandomi quell'errore strano quando facevo l'update... rifare le tabelle è stato l'unico modo che mi ha permesso di risolvere
Grazie per l'interesse
229 messaggi dal 20 novembre 2014
Ciao Moreno,
mi ritrovo di nuovo con un errore sempre legato a quella mappatura fatta che mi sta facendo impazzire. Dunque riepilogo la mappatura coinvolta

"Ogni operatore può avere una o più abilitazioni"
model Personale
public class Personale
{
//Faccio l'hashset per la mappatura Personale->OperatoriAbilitatiInterventi
public Personale()
{
OperatoreAbilitatoIntervento = new HashSet<OperatoriAbilitatiInterventi>();
}

[Key]
public int IDPersonale { get; set; }
[StringLength(200)]
[Display(Name = "Nome")]
public string Nome { get; set; }
[StringLength(200)]
[Display(Name = "Cognome")]
public string Cognome { get; set; }
[StringLength(100)]
[Display(Name = "Nome Utente")]
public string NomeUtente { get; set; }
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
//[StringLength(500)]
[Display(Name = "Ruolo")]
public int Ruolo { get; set; }
public Boolean Attivo { get; set; }

public virtual ICollection<OperatoriAbilitatiInterventi> OperatoreAbilitatoIntervento { get; set; }
}

model OperatoriAbilitatiInterventi
public class OperatoriAbilitatiInterventi
{

//Mappatura uno ad uno Tipo_TipoInterventi
public virtual Tipo_TipoInterventi TipoTipoIntervento { get; set; }

[Key]

public int IDOperatoreAbilitato { get; set; }
[Display(Name = "Operatore")]
public int IdOperatore { get; set; }
[Display(Name = "Intervento")]
public int IdIntervento { get; set; }

public virtual Personale Personale { get; set; }

public string Utente { get; set; }
public DateTime Modifica { get; set; }

[Display(Name = "Attivo")]
public Boolean Attivo { get; set; }

}
Mappatura
//Mappatura per associazione Personale->OperatoriAbilitatiInterventi
modelBuilder.Entity<Personale>()
//personale ha una collezione di operatori
.HasMany(personale => personale.OperatoreAbilitatoIntervento)
//non può esistere un record in operatoriabilitatiinterventi
//se non lo associo ad un personale
.WithRequired(oai => oai.Personale)
//per come è stata mappata la relazione,
//la foreign key si trova su operatoriabilitatiinterventi
.HasForeignKey(oai => oai.IdOperatore);

Il problema si verifica quando cerco di creare un "Operatore abilitato" ho la tendina con la lista operatori, lo seleziono, seleziono l'intervento a cui è abilitato, salvo e mi da l'errore dicendo che è impossibile utilizzare una chiave ripetuta, prova a mettere sempre 0 come IDOperatoreAbilitato quindi ho troncato la tabella, ho settato l'identity autoincrementale sul db e adesso mi dice:
"System.Data.Entity.Core.UpdateException: Errore durante l'aggiornamento delle voci. Per ulteriori dettagli, vedere l'eccezione interna. ---> System.Data.SqlClient.SqlException: Quando IDENTITY_INSERT è OFF non è possibile inserire un valore esplicito per la colonna Identity nella tabella 'OperatoriAbilitatiInterventi'.
"
ho sempre usato l'identity in questo modo e non ho mai avuto problemi, mai visto questo errore, quindi penso che possa essere legato alla mappatura.
Mi daresti una dritta?
Grazie

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.