ASP.NET Core DB First scaffolding Join doesn't work

asp.net-core c# entity-framework-core

Question

I've created a test ASP.NET Core project. I've generated the models from an existing DB using the Scaffold-DbContext command.

Everything went fine. I've added an ApiController to return the data, and if I query, using LINQ, simple flat table data or I make joins on tables where the foreign keys have been explicitly defined in the DB it works.

But if I make a query joining two tables where the foreign keys have not been set it doesn't return anything.

Please note that the two tables are related to each other by an integer ID (MktId).

Entity models generated by the 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; }
}

the following query return results:

var price= (from m in db.MonthlyPrice
           join c in db.Commodities on m.CmId equals c.CmId
           select new
           {
               c.CmName,
               m.MpPrice
           });

but this one doesn't return anything:

var price= (from m in db.MonthlyPrice
           join mk in db.Markets on m.MktId equals mk.MktId
           select new
           {
               m.MpPrice,
               mk.MktName
           });

Please note that both queries on Entity Framework 6.x on ASP.NET 4.7 works perfectly.

Should I have to specify all the foreign key in the DB to make EFCore works correctly?

(Db is not always designed by me!!)

UPDATE

The model builder for the Markets has been generated by scaffold-dbcontext command like the following:

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);    
});

Respect to the one generated for Commodities table I've noticed that there is the line entity.ToTable("__Markets"); that looks very strange to me.

1
1
3/10/2019 7:53:58 PM

Popular Answer

  1. If you want to fight with it a bit:

Update to at least .NET Core 2.1

Preserve the original database names to remove the funk in the migration. Use the -UseDatabaseNames option.

scaffold-dbcontext  -UseDatabaseNames 
  1. Else, continue:

Annotations might be valuable either way if your ids or table names on the current database are funky (spaces, prefixes, etc...)

Add Markets to MonthlyPrice Class as a foreign key. Make the ids obvious to the migration using data annotations.

[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; }
}

If recreating database:

Add-Migration awesome

Update-Database awesome

Else, if just adding a migration:

Add-Migration awesome –IgnoreChanges

I guess the great thing is, you have a golden opportunity to make it better than the last guy. Starting out with Same-Same on everything (table names, column names, keys, would be nice). Clean up all the differences.

There are clearly differences in both your table name and primary key names currently.

0
3/10/2019 10:51:09 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow