.NET核心实体框架InvalidOperationException

Red*_*ter 4 c# entity-framework entity-framework-core .net-core

我有一个简单的模型

[Table("InterfaceType")]
public class InterfaceType
{
    [Key]
    public int InterfaceTypeId { get; set; }
    public string Description { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

在我的DbContext中

public DbSet<InterfaceType> InterfaceTypes { get; set; }
Run Code Online (Sandbox Code Playgroud)

在我的控制器里

List<InterfaceType> types = _context.InterfaceTypes.FromSql(
            "SELECT * FROM [Interfaces].[Control].[InterfaceType]").ToList();
Run Code Online (Sandbox Code Playgroud)

哪个返回错误:

InvalidOperationException:'FromSql'操作的结果中不存在所需的列'InterfaceID'.

我在其他类似的方法中使用FromSql没有问题,尽管这些模型确实包含InterfaceId.为什么当操作不在模型中时,此操作需要InterfaceId.我也尝试了以下相同的结果.

List<InterfaceType> types = _context.InterfaceTypes.FromSql(
            "SELECT InterfaceTypeId, Description FROM [Interfaces].[Control].[InterfaceType]").ToList();
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

interfacesOverview.SelectedInterface.InterfaceTypes = _context.InterfaceTypes.ToList();
Run Code Online (Sandbox Code Playgroud)

通过流畅的api声明后:

 protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
       modelBuilder.Entity<InterfaceType>().ToTable("InterfaceType", "Control");
    }
Run Code Online (Sandbox Code Playgroud)

结果相同.

为清楚起见,这里是MSSQL中的表:

    CREATE TABLE [Control].[InterfaceType](
    [InterfaceTypeId] [tinyint] NOT NULL,
    [Description] [varchar](25) NULL,
 CONSTRAINT [PK_InterfaceType] PRIMARY KEY CLUSTERED 
(
    [InterfaceTypeId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

UPDATE

我看过EF正在生成的SQL:

    SELECT [i].[InterfaceTypeId], [i].[Description], [i].[InterfaceID] FROM [Control].[InterfaceType] AS [i]
Run Code Online (Sandbox Code Playgroud)

从哪里获取InterfaceID?

Iva*_*oev 5

从哪里获取InterfaceID?

首先,应该清楚的是,它并非来自所示的"简单"(但显然是不完整的)模型.

EF生成的SQL清楚地表明您没有重命名PK属性生成列,也没有Discriminator列,因此它不能来自继承.并且您明确定义了一个被调用的阴影属性InterfaceID并且没有注意到它的可能性很小.

所有这一切,以及名称InterfaceID与我的FK属性/列名称的EF Core常规名称之一匹配的事实清楚地表明了由关系引入的传统FK.例如,有这样的第二个模型:

public class Interface
{
    public int ID { get; set; }
    // or
    // public int InterfaceID { get; set; }
    public ICollection<InterfaceType> InterfaceTypes { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

关系 - 单导航属性 EF Core文档主题中所述:

只包含一个导航属性(没有反向导航,没有外键属性)足以具有约定定义的关系.

并且附带的示例显示Blog/ Post模型,仅突出显示public List<Post> Posts { get; set; }属性Blog.

所有EF Core运行时行为都基于模型元数据.无论数据库的结构是什么,更重要的是EF Core认为它基于您的模型类,数据注释和流畅的配置,以及是否与数据库模式匹配.检查它的更简单方法是生成迁移并检查它是否与数据库模式匹配.

因此,如果关系是有意的,那么您必须更新数据库以匹配您的模型.否则,您需要更新模型以匹配数据库 - 通过删除或忽略集合导航属性(或更正导致差异的无效数据注释/流畅配置).