为了账号安全,请及时绑定邮箱和手机立即绑定

.NET Core 实体框架 InvalidOperationException

.NET Core 实体框架 InvalidOperationException

C#
慕田峪7331174 2022-06-12 14:32:55
我有一个简单的模型[Table("InterfaceType")]public class InterfaceType{    [Key]    public int InterfaceTypeId { get; set; }    public string Description { get; set; }}在我的 DbContextpublic DbSet<InterfaceType> InterfaceTypes { get; set; }在我的控制器中List<InterfaceType> types = _context.InterfaceTypes.FromSql(            "SELECT * FROM [Interfaces].[Control].[InterfaceType]").ToList();哪个返回错误:InvalidOperationException:“FromSql”操作的结果中不存在所需的列“InterfaceID”。我在与此类似的其他方法中使用 FromSql 没有问题,尽管这些模型确实包含 InterfaceId。为什么此操作在模型中不存在时需要一个 InterfaceId。我也尝试了以下相同的结果。List<InterfaceType> types = _context.InterfaceTypes.FromSql(            "SELECT InterfaceTypeId, Description FROM [Interfaces].[Control].[InterfaceType]").ToList();我也试过:interfacesOverview.SelectedInterface.InterfaceTypes = _context.InterfaceTypes.ToList();通过 fluent api 声明后: protected override void OnModelCreating(ModelBuilder modelBuilder)    {       modelBuilder.Entity<InterfaceType>().ToTable("InterfaceType", "Control");    }结果相同。为了清楚起见,这里是 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]更新我查看了 EF 生成的 SQL:    SELECT [i].[InterfaceTypeId], [i].[Description], [i].[InterfaceID] FROM [Control].[InterfaceType] AS [i]它从哪里获取 InterfaceID?
查看完整描述

3 回答

?
慕神8447489

TA贡献1780条经验 获得超1个赞

它从哪里获取 InterfaceID?


首先,应该清楚它不是来自所示的“简单”(但显然不完整)模型。


EF生成的SQL清楚地表明你没有重命名PK属性生成的列,也没有Discriminator列,所以它不能来自继承。而且您明确定义了一个名为的影子属性InterfaceID而没有注意到它的可能性很小。


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


public class Interface

{

    public int ID { get; set; }

    // or

    // public int InterfaceID { get; set; }

    public ICollection<InterfaceType> InterfaceTypes { get; set; }

}

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


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


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


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


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


查看完整回答
反对 回复 2022-06-12
?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

我对这个问题的理解是,EF 在您的模型类中创建了一个影子属性 ,可能是通过在您的Interface模型中部分发现的关系。

此外,我觉得 EFCore 使用的 ModelSnapshot 与数据库中表的真实状态(可能是挂起的迁移)之间存在不匹配。仔细检查您的InterfaceTypein <YourDbContext>ModelSnapshot.cs,并检查是否缺少您的财产。


查看完整回答
反对 回复 2022-06-12
?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

我的猜测是,您还在上下文中注册了一个“接口”表,该表包含对 InterfaceType 的引用。Interface 将声明一个 InterfaceTypeId 字段,但是对于 EF,如果您将 HasOne 与 ForeignKey 一起使用,请检查您是否意外分配了以下内容:

.HasOne(x => x.InterfaceType).WithOne().HasForeignKey<InterfaceType>("InterfaceId");

在具有 InterfaceType 的接口的情况下,它将被映射得更像:

.HasOne(x => x.InterfaceType).WithMany();

这可能已经潜入您的其他关联实体之一。通常这些是自动完成选择错误类型而您没有注意到的错别字。如果您的任何类上都存在该映射,则 EF 将期望在 InterfaceType 上找到一个 InterfaceId 列。搜索一下HasForeignKey<InterfaceType>,看看有没有什么不寻常的地方。


查看完整回答
反对 回复 2022-06-12
  • 3 回答
  • 0 关注
  • 252 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号