繁体   English   中英

使用 EF Core 3.0 生成错误查询

[英]Wrong Query Generated with EF Core 3.0

我正在尝试使用简单的 where 子句从 SQL 服务器检索数据。 但是生成的查询不正确。此查询与 EF Core 2.2 完美配合,但在 EF Core 3 中会引发异常。

    public async Task<List<CharacterReplacements>> GetReplacementsAsync(int? replacementSetId)
    {
        var replacementQuery = _context.CharacterReplacements.AsQueryable();

        if (replacementSetId.HasValue)
        {
            replacementQuery = replacementQuery.Where(r => r.CharacterReplacementSetID == replacementSetId.Value); // .AsQueryable();
        }

        var replacementList = await replacementQuery.ToListAsync();

        return replacementList;
    }

[Serializable]
[Table("CharacterReplacementSets", Schema = "SYSTEM")]
public class CharacterReplacementSets
{
    [NavigationPropertyKey]
    [Key]
    public int CharacterReplacementSetID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public ICollection<CharacterReplacements> CharacterReplacements { get; set; }
    public ICollection<FormatField> FormatFields { get; set; }
    public string CreatedBy { get; set; }
    public DateTime CreatedOn { get; set; }
    public string UpdatedBy { get; set; }
    public DateTime? UpdatedOn { get; set; }
    public string DefaultEncoding { get; set; } // Default character set
    public string DefaultCharacter { get; set; }
    public CharacterReplacementSets()
    {
        CharacterReplacements = new List<CharacterReplacements>();
    }
}

[Serializable]
[Table("CharacterReplacements", Schema = "SYSTEM")]
public class CharacterReplacements
{
    [NavigationPropertyKey]
    [Key]
    public int CharacterReplacementID { get; set; }
    public char OriginalCharacter { get; set; }
    public string ReplacementCharacter { get; set; }
    public string CreatedBy { get; set; }
    public DateTime CreatedOn { get; set; }
    public string UpdatedBy { get; set; }
    public DateTime? UpdatedOn { get; set; }
    [ForeignKey("CharacterReplacementSets")]
    public int CharacterReplacementSetID { get; set; }
}

预期结果 - 检索所有 CharacterReplacements,其中 replacementSetId 等于提供的 replacementSetId。

实际结果 - Microsoft.Data.SqlClient.SqlException:'无效的列名'CharacterReplacementSetsCharacterReplacementSetID'。

有人可以帮我解决这个问题吗?

问题不是具体查询,而是model映射。

一、这里的ForeignKey属性

[ForeignKey("CharacterReplacementSets")]
public int CharacterReplacementSetID { get; set; }

没有效果。 当应用于导航属性时,它应该指定 FK属性名称。 当应用到 FK 属性上时,它应该指定导航属性名称。 CharacterReplacements没有名为CharacterReplacementSets的导航属性,因此该属性被简单地忽略。 如果 EF Core 生成运行时错误以指示映射问题,那就太好了,但事实并非如此。

EF Core 1.x / 2.x 中也忽略了该属性。 但是它起作用了,因为属性CharacterReplacementSetID的名称与CharacterReplacementSets的 PK 的名称相匹配。 由于以下重大更改,EF Core 3.0 不再如此 - 外键属性约定不再与主体属性匹配相同的名称

所以删除不正确和误导性的ForeignKey属性,并通过HasForeignKey fluent API (我的首选)配置 FK 属性:

modelBuilder.Entity<CharacterReplacementSets>()
    .HasMany(e => e.CharacterReplacements)
    .WithOne()
    .HasForeignKey(e => e.CharacterReplacementSetID);

或在导航属性上使用ForegnKey属性(或在此处没有导航属性时使用反向导航属性):

[ForeignKey("CharacterReplacementSetID")]
public ICollection<CharacterReplacements> CharacterReplacements { get; set; }

请注意,您可能会遇到与FormatField和其他使用类似命名的 FK(不带导航属性)的实体类似的问题。

避免此问题的另一种方法是使用单一实体 class 名称,例如CharacterReplacementSetCharacterReplacement等,因为[entity name] + ID仍然符合 EF Core 约定。 通常单数 class 名称更好/更可取,即使只是为了可读性。

尝试调试生成的 sql 语句。 它正在寻找名为“CharacterReplacementSetsCharacterReplacementSetID”的列。但您的代码暗示该列名为“CharacterReplacementSetID”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM