我正在尝试使用一个简单的where子句从SQL Server检索数据。但是,生成的查询不正确。此查询与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,其中replaceSetId等于提供的replaceSetId。
实际结果- Microsoft.Data.SqlClient.SqlException:'无效的列名'CharacterReplacementSetsCharacterReplacementSetID'。
有人可以帮我吗?
答案 0 :(得分:1)
问题不是特定的查询,而是模型映射。
首先,这里的ForeignKey
属性
[ForeignKey("CharacterReplacementSets")]
public int CharacterReplacementSetID { get; set; }
无效。应用于导航属性时,应指定FK 属性名称。并按如下所示在FK属性上应用时,应指定导航属性名称。 CharacterReplacements
没有名为CharacterReplacementSets
的导航属性,因此该属性将被忽略。如果EF Core生成运行时错误来指示映射问题,那是很好的,但事实并非如此。
该属性在EF Core 1.x / 2.x中也被忽略。但是之所以起作用,是因为属性CharacterReplacementSetID
的名称与CharacterReplacementSets
的PK名称匹配。由于以下重大更改-The foreign key property convention no longer matches same name as the principal property,对于EF Core 3.0而言,情况不再如此。
因此,请删除不正确且具有误导性的ForeignKey
属性,然后通过HasForeignKey
流利的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且没有导航属性的实体可能会遇到类似问题。
避免此问题的另一种方法是使用单个实体类名称,例如CharacterReplacementSet
,CharacterReplacement
等,因为[entity name] + ID
仍与EF Core约定匹配。通常,单单的类名是更好/更可取的,即使只是为了提高可读性。