[英]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 名称,例如CharacterReplacementSet
、 CharacterReplacement
等,因为[entity name] + ID
仍然符合 EF Core 约定。 通常单数 class 名称更好/更可取,即使只是为了可读性。
尝试调试生成的 sql 语句。 它正在寻找名为“CharacterReplacementSetsCharacterReplacementSetID”的列。但您的代码暗示该列名为“CharacterReplacementSetID”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.