Ho creato un progetto di prova ASP.NET Core. Ho generato i modelli da un DB esistente usando il comando Scaffold-DbContext.
Tutto è andato bene. Ho aggiunto un ApiController per restituire i dati, e se eseguo una query, usando LINQ, semplici dati di tabella piatta o faccio join su tabelle in cui le chiavi esterne sono state esplicitamente definite nel DB, funziona.
Ma se eseguo una query unendo due tabelle in cui non sono state impostate le chiavi esterne, non restituisce nulla .
Si noti che le due tabelle sono correlate tra loro da un ID intero ( MktId ).
Modelli di entità generati dallo scaffold:
public partial class MonthlyPrice
{
public int MpId { get; set; }
public int MktId { get; set; }
public int CmId { get; set; }
public decimal MpPrice { get; set; }
public Commodities Cm { get; set; }
public Currencies Cur { get; set; }
public PriceTypes Pt { get; set; }
public UnitOfMeasure Um { get; set; }
}
public partial class Commodities
{
public Commodities()
{
MonthlyPriceItem = new HashSet<MonthlyPriceItem>();
}
public int CmId { get; set; }
public string CmName { get; set; }
public int CmCatId { get; set; }
public ICollection<MonthlyPrice> MonthlyPriceItem { get; set; }
}
public partial class Markets
{
public int MktId { get; set; }
public string MktName { get; set; }
}
la seguente query restituisce risultati:
var price= (from m in db.MonthlyPrice
join c in db.Commodities on m.CmId equals c.CmId
select new
{
c.CmName,
m.MpPrice
});
ma questo non restituisce nulla:
var price= (from m in db.MonthlyPrice
join mk in db.Markets on m.MktId equals mk.MktId
select new
{
m.MpPrice,
mk.MktName
});
Si noti che entrambe le query su Entity Framework 6.x su ASP.NET 4.7 funzionano perfettamente .
Devo specificare tutta la chiave esterna nel DB per far funzionare correttamente EFCore?
(Db non è sempre progettato da me !!)
AGGIORNARE
Il modello builder per i mercati è stato generato dal comando scaffold-dbcontext come il seguente:
modelBuilder.Entity<Markets1>(entity =>
{
entity.HasKey(e => e.MktId);
entity.ToTable("__Markets");
entity.Property(e => e.MktId).HasColumnName("mkt_id");
entity.Property(e => e.MktName)
.IsRequired()
.HasColumnName("mkt_name")
.HasMaxLength(250);
});
Rispetto a quello generato per la tabella delle materie prime ho notato che esiste l' entità linea.ToTable ("__ Markets"); mi sembra molto strano.
Aggiornamento almeno a .NET Core 2.1
Conserva i nomi del database originale per rimuovere il funk nella migrazione. Utilizzare l'opzione -UseDatabaseNames.
scaffold-dbcontext -UseDatabaseNames
Le annotazioni potrebbero essere utili in entrambi i casi se i tuoi ID o nomi di tabella nel database corrente sono funky (spazi, prefissi, ecc ...)
Aggiungi i mercati alla classe MonthlyPrice come chiave esterna. Rendi gli ID ovvi alla migrazione usando le annotazioni dei dati.
[Table(“MonthlyPriceâ€)]
public partial class MonthlyPrice
{
[Key]
public int MpId { get; set; }
[ForeignKey("Markets")]
public int MktId { get; set; }
public Markets Mkt { get; set; }
[ForeignKey("Commodities")]
public int CmId { get; set; }
public Commodities Cm { get; set; }
public decimal MpPrice { get; set; }
public Currencies Cur { get; set; }
public PriceTypes Pt { get; set; }
public UnitOfMeasure Um { get; set; }
}
[Table(“Commoditiesâ€)]
public partial class Commodities
{
public Commodities()
{
MonthlyPriceItem = new HashSet<MonthlyPriceItem>();
}
[Key]
public int CmId { get; set; }
public string CmName { get; set; }
public int CmCatId { get; set; }
public ICollection<MonthlyPrice> MonthlyPriceItem { get; set; }
}
[Table(“Marketsâ€)]
public partial class Markets
{
[Key]
public int MktId { get; set; }
public string MktName { get; set; }
}
Se si ricrea un database:
Add-Migration awesome
Update-Database awesome
Altrimenti, se si sta semplicemente aggiungendo una migrazione:
Add-Migration awesome –IgnoreChanges
Immagino che la cosa grandiosa sia che tu abbia un'opportunità d'oro per renderlo migliore dell'ultimo ragazzo. Iniziare con Same-Same su tutto (nomi di tabelle, nomi di colonne, chiavi, sarebbe bello). Elimina tutte le differenze.
Attualmente ci sono chiaramente differenze sia nel nome della tabella che in quello della chiave primaria.