【问题标题】:ASP.NET Core DB First scaffolding Join doesn't workASP.NET Core DB First 脚手架连接不起作用
【发布时间】:2019-03-11 06:51:09
【问题描述】:

我创建了一个测试 ASP.NET Core 项目。我已经使用 Scaffold-DbContext 命令从现有数据库生成模型。

一切都很顺利。我添加了一个 ApiController 来返回数据,如果我使用 LINQ 查询简单的平面表数据,或者我在数据库中明确定义了外键的表上进行连接,它可以工作。

但是,如果我查询连接两个表没有设置外键,它不会返回任何内容

请注意,这两个表通过整数 ID (MktId) 相互关联。

脚手架生成的实体模型:

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

以下查询返回结果:

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

但是这个没有返回任何东西:

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

请注意在 ASP.NET 4.7 上的 Entity Framework 6.x 上的两个查询都可以完美运行

我是否必须指定数据库中的所有外键才能使 EFCore 正常工作?

(Db 并不总是由我设计的!!)

更新

市场的模型构建器已由scaffold-dbcontext 命令生成,如下所示:

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

关于为 Commodities 表生成的表格,我注意到有一行 entity.ToTable("__Markets"); 对我来说看起来很奇怪。

【问题讨论】:

  • 看起来MonthlyPriceMarket 之间的一对多关系没有在数据库中配置(至少正确)。此外,CommodityMarket 是否应该与MonthlyPrice 作为中间表存在多对多关系?
  • @David Liang 但是如果用于连接的 ID 的数量匹配,为什么它不返回任何东西?有时即使存在外键,也不会在数据库中配置外键。使用 EF6 我从来没有遇到过这个问题
  • 如果这个数据库是预先存在的,你可能想用命令行对你的上下文进行逆向工程。这样,它有望获得有效的起点。请记住,EF Core 的基本更改不会与前辈一一对应,即如果它在 EF6 中工作,它应该在 Core 中工作。并非总是如此。
  • @mvermef scaffold-dbcontext 是从数据库创建模型的命令。所以,你是在告诉我,我所面临的事情是不可能的,而且数据肯定有错误?
  • 不,我是说您拥有的配置可能与数据库的配置不匹配,这并不意味着您无法做到正确,您只需进行更多研究即可获得该配置首先在您的代码中正确配置一个。它可能只需要在您的代码级别进行调整。我只是建议反向脚手架可能会提供关系

标签: c# asp.net-core entity-framework-core


【解决方案1】:
  1. 如果你想和它战斗一下:

至少更新到 .NET Core 2.1

保留原始数据库名称以消除迁移中的恐惧。使用 -UseDatabaseNames 选项。

scaffold-dbcontext  -UseDatabaseNames 
  1. 否则,继续:

如果您在当前数据库中的 id 或表名很时髦(空格、前缀等),那么无论哪种方式,注释都可能很有价值

将 Markets 作为外键添加到 MonthlyPrice 类。使用数据注释使 id 对迁移显而易见。

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

如果重新创建数据库:

Add-Migration awesome

Update-Database awesome

否则,如果只是添加迁移:

Add-Migration awesome –IgnoreChanges

我想最棒的是,你有一个千载难逢的机会让它比上一个人做得更好。从所有东西(表名,列名,键,会很好)开始相同。清理所有差异。

目前你的表名和主键名明显不同。

【讨论】:

  • 这不是 db-first 方法
  • 邪恶空间毁了一切。包括数据库迁移。
猜你喜欢
  • 2017-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多